Skip to content

Commit

Permalink
feat: Implemented browser versions for reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
unlok committed Jul 28, 2020
1 parent ea8fec5 commit b19fd61
Show file tree
Hide file tree
Showing 32 changed files with 551 additions and 301 deletions.
8 changes: 0 additions & 8 deletions hermione.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

const os = require('os');
const PQueue = require('p-queue');

const utils = require('./lib/common-utils');
const PluginAdapter = require('./lib/plugin-adapter');
const createWorkers = require('./lib/workers/create-workers');

Expand Down Expand Up @@ -83,11 +81,5 @@ async function prepare(hermione, reportBuilder, pluginConfig) {
hermione.on(hermione.events.RUNNER_END, () => {
return Promise.all(promises).then(resolve, reject);
});

hermione.on(hermione.events.AFTER_TESTS_READ, (collection) => {
const browsers = utils.formatBrowsers(collection);

reportBuilder.setBrowsers(browsers);
});
});
}
20 changes: 2 additions & 18 deletions lib/common-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const {
const {
DB_MAX_AVAILABLE_PAGE_SIZE,
DB_SUITES_TABLE_NAME,
DB_BROWSERS_TABLE_NAME,
DB_TYPES
} = require('./constants/database');

Expand All @@ -34,7 +33,6 @@ exports.isUpdatedStatus = (status) => status === UPDATED;

exports.selectAllQuery = (tableName) => `SELECT * FROM ${tableName}`;
exports.selectAllSuitesQuery = () => exports.selectAllQuery(DB_SUITES_TABLE_NAME);
exports.selectAllBrowsersQuery = () => exports.selectAllQuery(DB_BROWSERS_TABLE_NAME);

exports.suitesTableColumns = [
{name: 'suitePath', type: DB_TYPES.text},
Expand All @@ -52,10 +50,6 @@ exports.suitesTableColumns = [
{name: 'timestamp', type: DB_TYPES.int}
];

exports.browsersTableColumns = [
{name: 'name', type: DB_TYPES.text}
];

exports.dbColumnIndexes = exports.suitesTableColumns.reduce((acc, {name}, index) => {
acc[name] = index;
return acc;
Expand All @@ -77,8 +71,7 @@ exports.determineStatus = (statuses) => {
};

exports.createTablesQuery = () => [
createTableQuery(DB_SUITES_TABLE_NAME, exports.suitesTableColumns),
createTableQuery(DB_BROWSERS_TABLE_NAME, exports.browsersTableColumns)
createTableQuery(DB_SUITES_TABLE_NAME, exports.suitesTableColumns)
];

function createTableQuery(tableName, columns) {
Expand All @@ -91,8 +84,7 @@ function createTableQuery(tableName, columns) {

exports.mergeTablesQueries = (dbPaths) => {
const tablesToMerge = [
DB_SUITES_TABLE_NAME,
DB_BROWSERS_TABLE_NAME
DB_SUITES_TABLE_NAME
];
const mkMergeQuery = (table) => `INSERT OR IGNORE INTO ${table} SELECT * FROM attached.${table}`;
const queries = [].concat(
Expand All @@ -112,11 +104,3 @@ exports.mergeTablesQueries = (dbPaths) => {
exports.compareDatabaseRowsByTimestamp = (row1, row2) => {
return row1[exports.dbColumnIndexes.timestamp] - row2[exports.dbColumnIndexes.timestamp];
};

exports.formatBrowsers = (collection) => {
return collection
.getBrowsers()
.map((name) => ({
id: name
}));
};
3 changes: 3 additions & 0 deletions lib/constants/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.versions = {
UNKNOWN: 'unknown'
};
1 change: 0 additions & 1 deletion lib/constants/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
module.exports = {
DB_MAX_AVAILABLE_PAGE_SIZE: 65536, // helps to speed up queries
DB_SUITES_TABLE_NAME: 'suites',
DB_BROWSERS_TABLE_NAME: 'browsers',
DB_TYPES: {
int: 'INT',
text: 'TEXT'
Expand Down
7 changes: 3 additions & 4 deletions lib/gui/tool-runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,24 +116,23 @@ module.exports = class ToolRunner {
const {autoRun} = this._guiOpts;
this._tree = {...this._reportBuilder.getResult(), gui: true, autoRun};

const {suites, browsers} = await this._applyReuseData(this._tree.suites);
const {suites} = await this._applyReuseData(this._tree.suites);

this._tree.suites = suites;
this._tree.browsers = browsers;
}

async _applyReuseData(testSuites) {
if (!testSuites) {
return {};
}

const {suites: preparedSuites, browsers} = await this._loadReuseData();
const {suites: preparedSuites} = await this._loadReuseData();

const suites = _.isEmpty(preparedSuites)
? testSuites
: testSuites.map((suite) => applyReuse(preparedSuites)(suite));

return {suites, browsers};
return {suites};
}

async _loadReuseData() {
Expand Down
7 changes: 0 additions & 7 deletions lib/gui/tool-runner/report-subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const {RUNNING} = require('../../constants/test-statuses');
const {getSuitePath} = require('../../plugin-utils').getHermioneUtils();
const {findTestResult, withErrorHandling} = require('./utils');
const createWorkers = require('../../workers/create-workers');
const utils = require('../../../lib/common-utils');

let workers;

Expand Down Expand Up @@ -107,10 +106,4 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {
hermione.on(hermione.events.RUNNER_END, async () => {
return client.emit(clientEvents.END);
});

hermione.on(hermione.events.AFTER_TESTS_READ, (collection) => {
const browsers = utils.formatBrowsers(collection);

reportBuilder.setBrowsers(browsers);
});
};
8 changes: 3 additions & 5 deletions lib/gui/tool-runner/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const NestedError = require('nested-error-stacks');
const {logger, logError} = require('../../server-utils');
const constantFileNames = require('../../constants/file-names');
const {findNode, setStatusForBranch} = require('../../static/modules/utils');
const {formatTestAttempt, formatBrowsersDataFromDb} = require('../../../lib/static/modules/database-utils');
const {mergeTablesQueries, selectAllSuitesQuery, selectAllBrowsersQuery, compareDatabaseRowsByTimestamp} = require('../../common-utils');
const {formatTestAttempt} = require('../../../lib/static/modules/database-utils');
const {mergeTablesQueries, selectAllSuitesQuery, compareDatabaseRowsByTimestamp} = require('../../common-utils');
const {writeDatabaseUrlsFile} = require('../../server-utils');

const formatTestHandler = (browser, test) => {
Expand Down Expand Up @@ -164,13 +164,11 @@ exports.getDataFromDatabase = (dbPath) => {
try {
const db = new Database(dbPath, {readonly: true, fileMustExist: true});
const suitesRows = db.prepare(selectAllSuitesQuery()).raw().all();
const browsersRows = db.prepare(selectAllBrowsersQuery()).raw().all();
const browsers = formatBrowsersDataFromDb(browsersRows);
const suites = parseDatabaseSuitesRows(suitesRows.sort(compareDatabaseRowsByTimestamp));

db.close();

return {...suites, browsers};
return suites;
} catch (err) {
throw new NestedError('Error while getting data from database ', err);
}
Expand Down
1 change: 0 additions & 1 deletion lib/report-builder/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ module.exports = class GuiReportBuilder extends StaticReportBuilder {

addSkipped(result) {
const formattedResult = super.addSkipped(result);

const {
suite: {
skipComment: comment,
Expand Down
4 changes: 0 additions & 4 deletions lib/report-builder/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ module.exports = class StaticReportBuilder {
: TestAdapter.create(result, this._hermione, this._pluginConfig, status);
}

setBrowsers(browsers) {
this._sqliteAdapter.writeBrowsers(browsers);
}

async saveStaticFiles() {
const destPath = this._pluginConfig.path;

Expand Down
11 changes: 1 addition & 10 deletions lib/sqlite-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const debug = require('debug')('html-reporter:sqlite-adapter');

const {createTablesQuery, suitesTableColumns} = require('./common-utils');
const {LOCAL_DATABASE_NAME, DATABASE_URLS_JSON_NAME} = require('./constants/file-names');
const {DB_SUITES_TABLE_NAME, DB_BROWSERS_TABLE_NAME} = require('./constants/database');
const {DB_SUITES_TABLE_NAME} = require('./constants/database');

module.exports = class SqliteAdapter {
static create(...args) {
Expand Down Expand Up @@ -59,15 +59,6 @@ module.exports = class SqliteAdapter {
this._db.prepare(`INSERT INTO ${DB_SUITES_TABLE_NAME} VALUES (${placeholders})`).run(...values);
}

writeBrowsers(browsers) {
const insert = this._db.prepare(`INSERT INTO ${DB_BROWSERS_TABLE_NAME} (name) VALUES (@id)`);
const insertBulk = this._db.transaction((bros) => {
bros.forEach((bro) => insert.run(bro));
});

return insertBulk(browsers);
}

_parseTestResult({suitePath, suiteName, testResult}) {
const {
name,
Expand Down
114 changes: 98 additions & 16 deletions lib/static/components/controls/browser-list.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,98 @@
'use strict';

import React, {Component} from 'react';
import {flatten, isEmpty} from 'lodash';
import {flatten, isEmpty, get, chain, compact} from 'lodash';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import TreeSelect, {SHOW_PARENT} from 'rc-tree-select';

import 'rc-tree-select/assets/index.less';

const ROOT_NODE_ID = 'ROOT_NODE_ID';

export default class BrowserList extends Component {
static propTypes = {
available: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string
id: PropTypes.string,
versions: PropTypes.arrayOf(PropTypes.string)
})).isRequired,
selected: PropTypes.arrayOf(PropTypes.string).isRequired,
selected: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
versions: PropTypes.arrayOf(PropTypes.string)
})),
onChange: PropTypes.func.isRequired
}

_buildComplexId(browserId, version) {
return version
? `${browserId} (${version})`
: browserId;
}

_prepareTreeData() {
const {available} = this.props;
const mkNode = (value, parentId) => ({
pId: parentId,
label: value,
key: value,
value
const mkNode = (parentId, browserId, version) => {
const id = this._buildComplexId(browserId, version);

return {
pId: parentId,
key: id,
label: id,
value: id,
data: {id, browserId, version}
};
};

const tree = available.map(({id: browserId, versions = []}) => {
if (isEmpty(versions) || versions.length === 1) {
return mkNode(ROOT_NODE_ID, browserId);
}

const rootNode = mkNode(ROOT_NODE_ID, browserId);
const subNodes = versions.map((version) => mkNode(rootNode.key, browserId, version));

return [].concat(rootNode, subNodes);
});

return available.map(({id}) => mkNode(id, 0));
return flatten(tree);
}

_buidSelectedItems() {
const {available, selected = []} = this.props;
const selectedItems = selected.map(({id, versions}) => {
const availableNode = available.find((item) => item.id === id);
const shouldDrawOnlyRootNode = get(availableNode, 'versions', []).length === 1 || isEmpty(versions);

if (shouldDrawOnlyRootNode) {
return this._buildComplexId(id);
}

return versions.map((version) => this._buildComplexId(id, version));
});

return flatten(selectedItems);
}

_formatSelectedData(selectedItems) {
const treeDataMap = this._simpleTree.reduce((map, item) => {
map[item.value] = item.data;

return map;
}, {});

return chain(selectedItems)
.reduce((map, id) => {
const {browserId, version} = treeDataMap[id] || {};
const versions = map[browserId] || [];

versions.push(version);

map[browserId] = versions;

return map;
}, {})
.map((versions, id) => ({id, versions: compact(versions)}))
.value();
}

_shouldNotRender() {
Expand All @@ -37,17 +104,30 @@ export default class BrowserList extends Component {
return (<div></div>);
}

const {selected, onChange} = this.props;
const tree = this._prepareTreeData();
const treeDataSimpleMode = {id: 'key', rootPId: 0};
this._simpleTree = this._prepareTreeData();

const treeDataSimpleMode = {id: 'key', rootPId: ROOT_NODE_ID};
const hasNestedLevels = this._simpleTree.find(node => node.pId !== ROOT_NODE_ID);
const removeIcon = (<i className="fa fa-times browserlist__icon-remove" aria-hidden="true"></i>);
const switcherIcon = (item) => {
if (item.isLeaf) {
return;
}

return item.expanded
? <i className="fa fa-minus browserlist__icon-tree" aria-hidden="true"></i>
: <i className="fa fa-plus browserlist__icon-tree" aria-hidden="true"></i>;
};
const dropdownClassName = classNames(
{'browserlist_linear': !hasNestedLevels},
);

return (
<div className="browserlist">
<TreeSelect
style={{
width: 'auto',
minWidth: '150px',
minWidth: '220px',
maxWidth: '400px'
}}
dropdownStyle={{
Expand All @@ -56,17 +136,19 @@ export default class BrowserList extends Component {
overflow: 'hidden',
zIndex: 50
}}
defaultValue={selected}
dropdownClassName={dropdownClassName}
switcherIcon={switcherIcon}
defaultValue={this._buidSelectedItems()}
showSearch={false}
treeCheckable
placeholder="Browsers"
treeData={flatten(tree)}
treeData={this._simpleTree}
treeNodeFilterProp="title"
treeDataSimpleMode={treeDataSimpleMode}
showCheckedStrategy={SHOW_PARENT}
removeIcon={removeIcon}
treeIcon={<i></i>}
onChange={onChange}
onChange={(selected) => this.props.onChange(this._formatSelectedData(selected))}
maxTagCount={2}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions lib/static/components/section/section-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class SectionCommon extends Component {
}

const visibleChildren = children.filter(child => shouldSuiteBeShown({suite: child, testNameFilter, strictMatchFilter, filteredBrowsers, errorGroupTests, viewMode}));

const childrenTmpl = visibleChildren.map((child) => {
const key = uniqueId(`${suite.suitePath}-${child.name}`);

Expand Down
6 changes: 3 additions & 3 deletions lib/static/modules/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,12 @@ export const findSameDiffs = ({suitePath, browser, stateName, fails}) => {
};
};

export const selectBrowsers = (browserIds) => {
setFilteredBrowsers(browserIds);
export const selectBrowsers = (browsers) => {
setFilteredBrowsers(browsers);

return triggerViewChanges({
type: actionNames.BROWSERS_SELECTED,
payload: {browserIds}
payload: {browsers}
});
};

Expand Down
Loading

0 comments on commit b19fd61

Please sign in to comment.