-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embed feature #476
Merged
Merged
Embed feature #476
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
886cf51
handlebars bootstrap
evmiguel 0de0806
Structural implementation
evmiguel 347a865
Open reports page on button click
evmiguel a4316a3
Initial styling pass
evmiguel 825afcd
button styling
evmiguel fac9089
Adding JS behaviors
evmiguel 250e72d
Prod config
evmiguel 2c540c1
Fixing pathing issue for environments
evmiguel c209aa8
APG integration fixes
evmiguel c985dc8
Adding condition for no data
evmiguel d6dfff1
Adding view cache
evmiguel 298603b
Reports sorted by AT with logic to populate columns
evmiguel 999b782
Remove console statement
evmiguel ed65d66
Cleanup
evmiguel e4d7c8c
Post message as object instead of string
evmiguel 886b2f9
Addressing PR feedback, adding copied message to the right, and addin…
evmiguel 9b17044
Adding recommended notice
evmiguel 3eb1cd5
Removing cacheing
evmiguel 97eea63
Make responsive (#477)
alflennik 360ece2
Surface AT version
evmiguel 8aa4157
Adding caching
evmiguel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
const express = require('express'); | ||
const { resolve } = require('path'); | ||
const { create } = require('express-handlebars'); | ||
const { | ||
ApolloClient, | ||
gql, | ||
HttpLink, | ||
InMemoryCache | ||
} = require('@apollo/client'); | ||
const fetch = require('cross-fetch'); | ||
|
||
const app = express(); | ||
const handlebarsPath = | ||
process.env.ENVIRONMENT === 'dev' ? 'handlebars' : 'server/handlebars'; | ||
|
||
// handlebars | ||
const hbs = create({ | ||
layoutsDir: resolve(`${handlebarsPath}/views/layouts`), | ||
extname: 'hbs', | ||
defaultLayout: 'index', | ||
helpers: require(resolve(`${handlebarsPath}/helpers`)) | ||
}); | ||
|
||
app.engine('hbs', hbs.engine); | ||
app.set('view engine', 'hbs'); | ||
app.set('views', resolve(`${handlebarsPath}/views`)); | ||
|
||
if (process.env.ENVIRONMENT !== 'dev') { | ||
app.enable('view cache'); | ||
} | ||
|
||
const client = new ApolloClient({ | ||
link: new HttpLink({ uri: 'http://localhost:5000/api/graphql', fetch }), | ||
cache: new InMemoryCache() | ||
}); | ||
|
||
const getLatestReportsForPattern = async pattern => { | ||
const { data } = await client.query({ | ||
query: gql` | ||
query { | ||
testPlanReports(statuses: [CANDIDATE, RECOMMENDED]) { | ||
id | ||
metrics | ||
status | ||
at { | ||
id | ||
name | ||
} | ||
browser { | ||
id | ||
name | ||
} | ||
finalizedTestResults { | ||
id | ||
atVersion { | ||
id | ||
name | ||
releasedAt | ||
} | ||
} | ||
runnableTests { | ||
id | ||
} | ||
draftTestPlanRuns { | ||
testResults { | ||
test { | ||
id | ||
} | ||
} | ||
} | ||
testPlanVersion { | ||
id | ||
updatedAt | ||
testPlan { | ||
id | ||
} | ||
} | ||
} | ||
} | ||
` | ||
}); | ||
|
||
const testPlanReports = data.testPlanReports.filter( | ||
report => report.testPlanVersion.testPlan.id === pattern | ||
); | ||
|
||
const latestTestPlanVersionId = testPlanReports.sort( | ||
(a, b) => | ||
new Date(a.testPlanVersion.updatedAt) - | ||
new Date(b.testPlanVersion.updatedAt) | ||
)[0]?.testPlanVersion.id; | ||
|
||
const latestReports = testPlanReports.filter( | ||
report => report.testPlanVersion.id === latestTestPlanVersionId | ||
); | ||
|
||
let allAts = new Set(); | ||
let allBrowsers = new Set(); | ||
let allAtVersionsByAt = {}; | ||
let status = 'RECOMMENDED'; | ||
let reportsByAt = {}; | ||
|
||
latestReports.forEach(report => { | ||
allAts.add(report.at.name); | ||
allBrowsers.add(report.browser.name); | ||
if (report.status === 'CANDIDATE') { | ||
status = report.status; | ||
} | ||
|
||
allAtVersionsByAt[report.at.name] = report.finalizedTestResults | ||
.map(result => result.atVersion) | ||
.reduce((prev, current) => | ||
new Date(prev.releasedAt) > new Date(current.releasedAt) | ||
? prev | ||
: current | ||
); | ||
}); | ||
|
||
allBrowsers = Array.from(allBrowsers).sort(); | ||
|
||
allAts.forEach(at => { | ||
reportsByAt[at] = latestReports | ||
.filter(report => report.at.name === at) | ||
.sort((a, b) => a.browser.name.localeCompare(b.browser.name)); | ||
}); | ||
|
||
return { | ||
allBrowsers, | ||
allAtVersionsByAt, | ||
latestTestPlanVersionId, | ||
status, | ||
reportsByAt | ||
}; | ||
}; | ||
|
||
app.get('/reports/:pattern', async (req, res) => { | ||
const pattern = req.params.pattern; | ||
const protocol = process.env.ENVIRONMENT === 'dev' ? 'http://' : 'https://'; | ||
const { | ||
allBrowsers, | ||
allAtVersionsByAt, | ||
latestTestPlanVersionId, | ||
status, | ||
reportsByAt | ||
} = await getLatestReportsForPattern(pattern); | ||
res.render('main', { | ||
layout: 'index', | ||
dataEmpty: Object.keys(reportsByAt).length === 0, | ||
pattern, | ||
status, | ||
allBrowsers, | ||
allAtVersionsByAt, | ||
reportsByAt, | ||
completeReportLink: `${protocol}${req.headers.host}/report/${latestTestPlanVersionId}`, | ||
embedLink: `${protocol}${req.headers.host}/embed/reports/${pattern}` | ||
}); | ||
}); | ||
|
||
app.use(express.static(resolve(`${handlebarsPath}/public`))); | ||
|
||
module.exports = app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
let map = {}; | ||
|
||
module.exports = { | ||
isBrowser: function(a, b) { | ||
return a === b; | ||
}, | ||
isInAllBrowsers: function(value, object) { | ||
return object.allBrowsers.includes(value); | ||
}, | ||
isCandidate: function(value) { | ||
return value === 'CANDIDATE'; | ||
}, | ||
getAtVersion: function(object, key) { | ||
return object.allAtVersionsByAt[key].name; | ||
}, | ||
elementExists: function(parentObject, childObject, at, key, last) { | ||
const atBrowsers = childObject.map(o => o.browser.name); | ||
|
||
if (!map[parentObject.pattern]) { | ||
map[parentObject.pattern] = {}; | ||
} | ||
|
||
if (!(at in map[parentObject.pattern])) { | ||
map[parentObject.pattern][at] = {}; | ||
} | ||
|
||
const moreThanOneColumn = Object.values(childObject).length > 1; | ||
|
||
const conditional = | ||
moreThanOneColumn && | ||
(key in map[parentObject.pattern][at] || atBrowsers.includes(key)); | ||
|
||
// Cache columns that don't have data | ||
if ( | ||
!(key in map[parentObject.pattern][at]) && | ||
!atBrowsers.includes(key) | ||
) { | ||
map[parentObject.pattern][at][key] = true; | ||
} | ||
|
||
// Don't write to the Safari column unless it's the last element | ||
if (!last && key === 'Safari' && !atBrowsers.includes(key)) { | ||
return true; | ||
} else if (last && key === 'Safari' && !atBrowsers.includes(key)) { | ||
return false; | ||
} | ||
|
||
return conditional; | ||
}, | ||
resetMap: function() { | ||
map = {}; | ||
return; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const iframeClass = `support-levels-${document.currentScript.getAttribute( | ||
'pattern' | ||
)}`; | ||
|
||
const iframeCode = link => | ||
` <iframe | ||
class="${iframeClass}" | ||
src="${link}" | ||
height="500" | ||
allow="clipboard-write" | ||
style="border-style: none; width: 100%;"> | ||
</iframe>`; | ||
|
||
// eslint-disable-next-line no-unused-vars | ||
const announceCopied = link => { | ||
navigator.clipboard.writeText(iframeCode(link)); | ||
const parentDiv = document.getElementById('copied-message'); | ||
const innerDiv = document.createElement('div'); | ||
const innerText = document.createTextNode('Embed link copied.'); | ||
innerDiv.appendChild(innerText); | ||
innerDiv.setAttribute('role', 'alert'); | ||
if (!parentDiv.firstChild) { | ||
parentDiv.appendChild(innerDiv); | ||
} | ||
setTimeout(() => { | ||
document.getElementById('copied-message').removeChild(innerDiv); | ||
}, 5000); | ||
}; | ||
|
||
const postHeightAndClass = () => | ||
window.parent.postMessage( | ||
{ height: document.body.scrollHeight, iframe: iframeClass }, | ||
'*' | ||
); | ||
|
||
window.onresize = postHeightAndClass; | ||
postHeightAndClass(); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we format the string like this? This formatting would require less correction when embedded.