-
Notifications
You must be signed in to change notification settings - Fork 39
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
perf: increase html-reporter performance #492
Changes from all commits
8bf190a
2bbe181
d0df053
957617b
89b8618
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
'use strict'; | ||
|
||
const axios = require('axios'); | ||
const {get} = require('lodash'); | ||
const serverUtils = require('../server-utils'); | ||
|
||
module.exports = async (pluginConfig, hermione, srcPaths, {destination: destPath}) => { | ||
validateOpts(srcPaths, destPath); | ||
|
||
const resolvedUrls = await tryResolveUrls(srcPaths); | ||
|
||
await Promise.all([ | ||
serverUtils.saveStaticFilesToReportDir(hermione, pluginConfig, destPath), | ||
serverUtils.writeDatabaseUrlsFile(destPath, srcPaths) | ||
serverUtils.writeDatabaseUrlsFile(destPath, resolvedUrls) | ||
]); | ||
|
||
await hermione.htmlReporter.emitAsync(hermione.htmlReporter.events.REPORT_SAVED, {reportPath: destPath}); | ||
|
@@ -22,3 +26,42 @@ function validateOpts(srcPaths, destPath) { | |
throw new Error(`Destination report path: ${destPath}, exists in source report paths`); | ||
} | ||
} | ||
|
||
async function tryResolveUrls(urls) { | ||
const resolvedUrls = []; | ||
const results = await Promise.all(urls.map(tryResolveUrl)); | ||
|
||
results.forEach(({jsonUrls, dbUrls}) => { | ||
resolvedUrls.push(...jsonUrls.concat(dbUrls)); | ||
}); | ||
|
||
return resolvedUrls; | ||
} | ||
|
||
async function tryResolveUrl(url) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Рекурсивно проходит по всем вложенным |
||
const jsonUrls = []; | ||
const dbUrls = []; | ||
|
||
if (serverUtils.isDbUrl(url)) { | ||
dbUrls.push(url); | ||
} else if (serverUtils.isJsonUrl(url)) { | ||
try { | ||
const {data} = await axios.get(url); | ||
const currentDbUrls = get(data, 'dbUrls', []); | ||
const currentJsonUrls = get(data, 'jsonUrls', []); | ||
|
||
const responses = await Promise.all(currentJsonUrls.map(tryResolveUrl)); | ||
|
||
dbUrls.push(...currentDbUrls); | ||
|
||
responses.forEach(response => { | ||
dbUrls.push(...response.dbUrls); | ||
jsonUrls.push(...response.jsonUrls); | ||
}); | ||
} catch (e) { | ||
jsonUrls.push(url); | ||
} | ||
} | ||
|
||
return {jsonUrls, dbUrls}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,7 +131,8 @@ export async function saveStaticFilesToReportDir(htmlReporter: HtmlReporter, plu | |
copyToReportDir(destPath, ['report.min.js', 'report.min.css'], staticFolder), | ||
fs.copy(path.resolve(staticFolder, 'index.html'), path.resolve(destPath, 'index.html')), | ||
fs.copy(path.resolve(staticFolder, 'icons'), path.resolve(destPath, 'icons')), | ||
fs.copy(require.resolve('@gemini-testing/sql.js'), path.resolve(destPath, 'sql-wasm.js')), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -2 МБ |
||
fs.copy(require.resolve('@gemini-testing/sql.js/dist/sql-wasm.js'), path.resolve(destPath, 'sql-wasm.js')), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
fs.copy(require.resolve('@gemini-testing/sql.js/dist/sql-wasm.wasm'), path.resolve(destPath, 'sql-wasm.wasm')), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
copyPlugins(pluginConfig, destPath) | ||
]); | ||
} | ||
|
@@ -168,10 +169,17 @@ export function urlPathNameEndsWith(currentUrl: string, searchString: string): b | |
} | ||
} | ||
|
||
export async function writeDatabaseUrlsFile(destPath: string, srcPaths: string[]): Promise<void> { | ||
const jsonUrls = srcPaths.filter(p => urlPathNameEndsWith(p, '.json')); | ||
const dbUrls = srcPaths.filter(p => urlPathNameEndsWith(p, '.db')); | ||
export function isJsonUrl(url: string): boolean { | ||
return urlPathNameEndsWith(url, '.json'); | ||
} | ||
|
||
export function isDbUrl(url: string): boolean { | ||
return urlPathNameEndsWith(url, '.db'); | ||
} | ||
|
||
export async function writeDatabaseUrlsFile(destPath: string, srcPaths: string[]): Promise<void> { | ||
const jsonUrls = srcPaths.filter(isJsonUrl); | ||
const dbUrls = srcPaths.filter(isDbUrl); | ||
const data = { | ||
dbUrls, | ||
jsonUrls | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,8 @@ export const initStaticReport = () => { | |
const mainDatabaseUrls = new URL('databaseUrls.json', window.location.href); | ||
const fetchDbResponses = await fetchDataFromDatabases([mainDatabaseUrls.href]); | ||
|
||
plugins.preloadAll(dataFromStaticFile.config); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Предзагрузка плагинов после того, как все базы загрузились, перед их слиянием. |
||
|
||
fetchDbDetails = fetchDbResponses.map(({url, status, data}) => ({url, status, success: !!data})); | ||
|
||
const dataForDbs = fetchDbResponses.map(({data}) => data).filter(data => data); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,17 +49,21 @@ const whitelistedDeps = { | |
// - an array with the string list of required dependencies and a function as the last item. | ||
// The function will be called with the dependencies as arguments plus `options` arg. | ||
|
||
const loadingPlugins = {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Предзагружаемые по сети плагины |
||
const pendingPlugins = {}; | ||
|
||
export default async function loadPlugin(pluginName, pluginConfig) { | ||
export function preloadPlugin(pluginName) { | ||
loadingPlugins[pluginName] = loadingPlugins[pluginName] || getScriptText(pluginName); | ||
} | ||
|
||
export async function loadPlugin(pluginName, pluginConfig) { | ||
if (pendingPlugins[pluginName]) { | ||
return pendingPlugins[pluginName]; | ||
} | ||
|
||
const pluginScriptPath = `plugins/${encodeURIComponent(pluginName)}/plugin.js`; | ||
const scriptTextPromise = loadingPlugins[pluginName] || getScriptText(pluginName); | ||
|
||
return pendingPlugins[pluginName] = Promise.resolve(pluginScriptPath) | ||
.then(getScriptText) | ||
return pendingPlugins[pluginName] = scriptTextPromise | ||
.then(executePluginCode) | ||
.then(plugin => initPlugin(plugin, pluginName, pluginConfig)) | ||
.then(null, err => { | ||
|
@@ -103,7 +107,13 @@ function executePluginCode(code) { | |
return exec(); | ||
} | ||
|
||
async function getScriptText(scriptUrl) { | ||
const result = await axios.get(scriptUrl); | ||
return result.data; | ||
function getPluginScriptPath(pluginName) { | ||
return `plugins/${encodeURIComponent(pluginName)}/plugin.js`; | ||
} | ||
|
||
async function getScriptText(pluginName) { | ||
const scriptUrl = getPluginScriptPath(pluginName); | ||
const {data} = await axios.get(scriptUrl); | ||
|
||
return data; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,16 @@ | ||
import actionNames from '../action-names'; | ||
import {applyStateUpdate} from '../utils'; | ||
|
||
export default (state, action) => { | ||
switch (action.type) { | ||
case actionNames.INIT_GUI_REPORT: | ||
case actionNames.INIT_STATIC_REPORT: { | ||
const {apiValues} = action.payload; | ||
|
||
return applyChanges(state, apiValues); | ||
return applyStateUpdate(state, {apiValues}); | ||
} | ||
|
||
default: | ||
return state; | ||
} | ||
}; | ||
|
||
function applyChanges(state, apiValues) { | ||
return { | ||
...state, | ||
apiValues: { | ||
...state.apiValues, | ||
...apiValues | ||
} | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,14 @@ | ||
import actionNames from '../action-names'; | ||
import {produce} from 'immer'; | ||
import {set} from 'lodash'; | ||
import {applyStateUpdate} from '../utils'; | ||
|
||
export default produce((draft, action) => { | ||
export default ((state, action) => { | ||
switch (action.type) { | ||
case actionNames.UPDATE_BOTTOM_PROGRESS_BAR: { | ||
const {currentRootSuiteId} = action.payload; | ||
|
||
return set(draft, 'progressBar.currentRootSuiteId', currentRootSuiteId); | ||
return applyStateUpdate(state, {progressBar: {currentRootSuiteId}}); | ||
} | ||
|
||
default: | ||
return draft; | ||
return state; | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
import {handleActiveResults, addGroupItem, sortGroupValues} from '../helpers'; | ||
import {ensureDiffProperty} from '../../../utils'; | ||
|
||
export function groupMeta({group, groupKey, ...restArgs}) { | ||
export function groupMeta({group, groupKey, diff = group, ...restArgs}) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь и далее |
||
const metaKeys = new Set(); | ||
if (groupKey) { | ||
group.byKey[groupKey] = {}; | ||
ensureDiffProperty(diff, ['byKey', groupKey]); | ||
} | ||
|
||
const resultCb = (result) => { | ||
|
@@ -18,14 +19,19 @@ export function groupMeta({group, groupKey, ...restArgs}) { | |
continue; | ||
} | ||
|
||
addGroupItem({group: group.byKey[groupKey], result, value}); | ||
addGroupItem({ | ||
group: group.byKey[groupKey], | ||
result, | ||
value, | ||
diff: diff.byKey[groupKey] | ||
Comment on lines
+23
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Так что дальше в функции они прокидываются так же, как и сами их |
||
}); | ||
} | ||
}; | ||
|
||
handleActiveResults({...restArgs, resultCb}); | ||
|
||
group.allKeys = [...metaKeys].sort(); | ||
diff.allKeys = [...metaKeys].sort(); | ||
if (groupKey) { | ||
group.byKey[groupKey] = sortGroupValues(group.byKey[groupKey]); | ||
diff.byKey[groupKey] = sortGroupValues(diff.byKey[groupKey]); | ||
} | ||
} |
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.
Все
urls
вставляются в один массив, потому что это позволяет не ломатьAPI
слияния отчетов