diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1c85384a7..50818a567 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,25 +2,39 @@ version: 2
jobs:
build:
docker:
- - image: cimg/node:12.18-browsers
+ - image: cimg/node:16.20-browsers
steps:
- - checkout
+ - checkout:
+ path: 'html-reporter'
- - run: npm install
+ - run: cd html-reporter && npm ci
+
+ - run:
+ name: Download Chromium
+ command: >-
+ cd test/func/docker/browser-utils &&
+ npm ci &&
+ CHROME_PATH=$(node download-chromium.js |& grep '^/home') &&
+ CHROME_PATH=$(dirname $CHROME_PATH) &&
+ mkdir ~/browsers &&
+ mv $CHROME_PATH ~/browsers/chrome-linux
+ cd ~/html-reporter
- run:
name: Download Selenium
- command: sudo npm install selenium-standalone@6.17.0 -g
+ command: npm install selenium-standalone@9.1.1 -g
- run:
name: Start Selenium
- command: selenium-standalone install && selenium-standalone start
+ command: >-
+ selenium-standalone install --drivers.chrome.version=116 &&
+ selenium-standalone start --drivers.chrome.version=116
background: true
- run:
name: Functional tests
- command: npm run test-func
+ command: npm run e2e
- store_artifacts:
- path: hermione-report/
- destination: /hermione-report
+ path: reports/
+ destination: /reports
diff --git a/.gitignore b/.gitignore
index 02378673b..99ba1f1fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ sqlite.db
hermione-report
/test/func/fixtures/report
+test/func/fixtures/plugins/html-reporter-plugins/*/plugin.js
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..dddd06ac7
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+# Contribution guide
+
+> This document is currently a work in progress and is not yet comprehensive.
+> Additional info will be added over time.
+
+### Running e2e tests
+
+End-to-end testing of html-reporter consists of two stages: generating fixture reports using different tools and tests,
+then running hermione tests on these reports.
+
+In order to make e2e/screenshot tests stable and reproducible across different environments,
+you need to launch browsers inside a Docker container.
+
+1. Make sure you have Docker installed.
+ How to?
+ 1. If you want to make a personal open-source contribution, you may use Docker free of charge and follow the [official guide](https://docs.docker.com/get-docker/).
+ 2. If you are acting on behalf of a company, you may not have access to Docker Desktop. In this case:
+ - On Linux, you may follow the official installation guide.
+ - On Mac, you may use [colima](https://github.com/abiosoft/colima) as a replacement for Docker Desktop.
+ - On Windows, you may use Windows Subsystem for Linux to run the Docker CLI without the Desktop application.
+
+2. Run e2e tests:
+ ```bash
+ npm run e2e
+ ```
+
+If you want a finer-grained control over the process, the following commands are available:
+- `npm run e2e:build-browsers` — build Docker image with browsers
+- `npm run e2e:launch-browsers` — launch selenium standalone server inside Docker
+- `npm run e2e:generate-fixture-report` — generate fixture report to run tests on
+- `npm run e2e:test` — run e2e tests
diff --git a/package.json b/package.json
index 37f3dc482..6bfbb08f2 100644
--- a/package.json
+++ b/package.json
@@ -16,17 +16,14 @@
"copy-static": "copyfiles 'lib/static/icons/*' .npmignore build",
"check-types": "tsc --project tsconfig.spec.json",
"coverage": "nyc npm run test-unit",
+ "e2e": "npm run e2e:launch-browsers && npm run e2e:generate-fixture-report -- --all && npm run e2e:test -- --all",
+ "e2e:build-browsers": "docker build -f test/func/docker/Dockerfile -t html-reporter-browsers:0.0.1 test/func/docker",
+ "e2e:generate-fixture-report": "node test/func/fixtures/cli.js",
+ "e2e:launch-browsers": "docker run -it --rm -p 4444:4444 html-reporter-browsers:0.0.1",
+ "e2e:test": "node test/func/tests/cli.js",
"lint": "eslint .",
"test": "npm run lint && npm run test-unit && npm run check-types",
"test-unit": "cross-env NODE_ENV=test mocha test/unit",
- "test-func": "npm run test-func-main && npm run test-func-plugins",
- "test-func-main": "npm run make-main-fixtures; cross-env NODE_ENV=test hermione",
- "test-func-plugins": "npm run make-plugins-fixtures; cross-env NODE_ENV=test hermione -c test/func/plugins/.hermione.plugins.js",
- "make-main-fixtures": "npm run clean-fixtures && cross-env NODE_ENV=test hermione -c test/func/fixtures/.hermione.fixtures.js",
- "make-plugins-fixtures": "npm run clean-fixtures && cross-env NODE_ENV=test html_reporter_plugins_enabled=true hermione -c test/func/fixtures/.hermione.fixtures.js",
- "make-main-fixtures-gui": "npm run make-main-fixtures -- gui",
- "make-plugins-fixtures-gui": "npm run make-plugins-fixtures -- gui",
- "clean-fixtures": "rimraf test/func/fixtures/report",
"precommit": "npm run lint",
"prepublishOnly": "npm run build",
"start": "NODE_ENV=development webpack serve --config=webpack.dev.js --progress",
@@ -127,7 +124,6 @@
"fork-ts-checker-webpack-plugin": "^6.5.3",
"hermione": "^8.0.0-beta.2",
"hermione-global-hook": "^1.0.1",
- "hermione-headless-chrome": "0.0.2",
"html-react-parser": "^0.4.0",
"html-reporter-basic-plugin": "file:test/func/html-reporter-plugins/basic",
"html-reporter-menu-bar-plugin": "file:test/func/html-reporter-plugins/menu-bar",
diff --git a/test/func/README.md b/test/func/README.md
deleted file mode 100644
index c23fd86f8..000000000
--- a/test/func/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-functional tests for html-reporter
-==================================
-
-Directories description:
-
-**main** - contains main set of suites for basic html-reporter features testing.
-
-```sh
-# To run functional tests on html-reporter main features
-> npm run test-func-main
-```
-
-**plugins** - set of suites for html-reporter plugins testing.
-
-```sh
-# To run functional tests on html-reporter plugins feature
-> npm run test-func-plugins
-```
-
-```sh
-# To run functional tests on both main features & html-reporter plugins feature
-> npm run test-func
-```
-
-**fixtures** - common set of fixture example tests to generate report for further functional tests.
-
-**hermione-plugins** - _hermione_ helper plugins to facilitate the functional tests.
-
-**html-reporter-plugins** - _html-reporter_ plugins for functional tests.
diff --git a/test/func/docker/.dockerignore b/test/func/docker/.dockerignore
new file mode 100644
index 000000000..cf7098890
--- /dev/null
+++ b/test/func/docker/.dockerignore
@@ -0,0 +1 @@
+**/node_modules
diff --git a/test/func/docker/Dockerfile b/test/func/docker/Dockerfile
new file mode 100644
index 000000000..b7d97ab02
--- /dev/null
+++ b/test/func/docker/Dockerfile
@@ -0,0 +1,20 @@
+FROM cimg/node:16.20-browsers
+
+ENV CHROME_VERSION=116
+
+USER circleci
+
+COPY --chown=circleci browser-utils browser-utils
+WORKDIR browser-utils
+
+RUN npm ci && \
+ # The download script outputs progress messages, but we need only final path, hence we filter output here
+ CHROME_PATH=$(node ./download-chromium.js |& grep '^/home') && \
+ CHROME_PATH=$(dirname $CHROME_PATH) && \
+ mkdir ~/browsers && \
+ mv $CHROME_PATH ~/browsers/chrome-linux
+
+RUN npm install selenium-standalone@9.1.1 -g && \
+ selenium-standalone install --drivers.chrome.version=$CHROME_VERSION
+
+ENTRYPOINT selenium-standalone start --drivers.chrome.version=$CHROME_VERSION
diff --git a/test/func/docker/browser-utils/download-chromium.js b/test/func/docker/browser-utils/download-chromium.js
new file mode 100644
index 000000000..e366148c2
--- /dev/null
+++ b/test/func/docker/browser-utils/download-chromium.js
@@ -0,0 +1,6 @@
+const os = require('os');
+const path = require('path');
+const downloadChromium = require('hermione-headless-chrome/lib/download-chromium-by-version');
+
+downloadChromium(process.env.CHROME_VERSION, path.join(os.homedir(), 'chrome-cache'), 10)
+ .then(chromePath => console.log(chromePath));
diff --git a/test/func/docker/browser-utils/package.json b/test/func/docker/browser-utils/package.json
new file mode 100644
index 000000000..06b2a6687
--- /dev/null
+++ b/test/func/docker/browser-utils/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "browser-utils",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {},
+ "dependencies": {
+ "hermione-headless-chrome": "1.1.0"
+ }
+}
diff --git a/test/func/fixtures/cli.js b/test/func/fixtures/cli.js
new file mode 100644
index 000000000..af91f0b9a
--- /dev/null
+++ b/test/func/fixtures/cli.js
@@ -0,0 +1,56 @@
+'use strict';
+
+const fs = require('fs/promises');
+const path = require('path');
+const util = require('util');
+const _ = require('lodash');
+const inquirer = require('inquirer');
+const program = require('@gemini-testing/commander');
+
+const exec = util.promisify(require('child_process').exec);
+
+const tasks = [
+ {project: 'hermione', task: () => exec('npx hermione', {cwd: path.resolve(__dirname, 'hermione')})},
+ {project: 'plugins', task: async () => {
+ const pluginNames = await fs.readdir('plugins');
+ await Promise.all(pluginNames.map(pluginName =>
+ exec('npm run build', {cwd: path.resolve(__dirname, 'hermione', pluginName)})
+ ));
+
+ return exec('npx hermione', {cwd: path.resolve(__dirname, 'plugins')});
+ }}
+];
+const allProjects = tasks.map(_.property('project'));
+
+(async () => {
+ program
+ .option('--all')
+ .option('-p --project [value]', '')
+ .parse(process.argv);
+
+ let selectedProjects = [];
+ if (program.all) {
+ selectedProjects = allProjects;
+ } else if (program.project) {
+ selectedProjects = program.project;
+ } else {
+ const {projects} = await inquirer.prompt([{
+ type: 'checkbox',
+ name: 'projects',
+ message: 'Select projects for which you want to generate fixture reports:',
+ choices: allProjects
+ }]);
+
+ selectedProjects = projects;
+ }
+
+ if (selectedProjects.some(p => !allProjects.includes(p))) {
+ throw new Error(`Project must be one of ${allProjects}`);
+ }
+
+ await Promise.all(tasks
+ .filter(task => selectedProjects.includes(task.project))
+ .map(task => task.task()));
+
+ console.log('All done!');
+})();
diff --git a/test/func/fixtures/failed-describe.hermione.js b/test/func/fixtures/failed-describe.hermione.js
deleted file mode 100644
index d688afe85..000000000
--- a/test/func/fixtures/failed-describe.hermione.js
+++ /dev/null
@@ -1,20 +0,0 @@
-describe('failed describe', function() {
- it('succesfully passed test', function() {
- return this.browser
- .url('')
- .then(() => assert.isTrue(true));
- });
-
- it('test without screenshot', function() {
- return this.browser
- .url('')
- .assertView('header', 'header');
- });
-
- it('test with long error message', function() {
- return this.browser
- .then(() => {
- throw new Error(`long_error_message ${'0123456789'.repeat(20)}\n message content`);
- });
- });
-});
diff --git a/test/func/fixtures/hermione/.hermione.conf.js b/test/func/fixtures/hermione/.hermione.conf.js
new file mode 100644
index 000000000..b0ef7cc3c
--- /dev/null
+++ b/test/func/fixtures/hermione/.hermione.conf.js
@@ -0,0 +1,44 @@
+'use strict';
+
+const {GRID_URL, CHROME_BINARY_PATH} = require('../../utils/constants');
+global.assert = require('chai').assert;
+
+const serverPort = 8080;
+const fixturesPath = 'test/func/fixtures/hermione/report';
+
+module.exports = {
+ gridUrl: GRID_URL,
+ baseUrl: `http://localhost:${serverPort}/test/func/fixtures/hermione/index.html`,
+
+ screenshotsDir: 'test/func/fixtures/screens',
+
+ sets: {
+ fixtures: {
+ files: 'test/func/fixtures/**/*.hermione.js'
+ }
+ },
+
+ browsers: {
+ chrome: {
+ windowSize: '1280x1024',
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ args: ['headless', 'no-sandbox'],
+ binary: CHROME_BINARY_PATH,
+ }
+ }
+ }
+ },
+
+ plugins: {
+ 'html-reporter-test-server': {
+ enabled: true,
+ port: serverPort
+ },
+ 'html-reporter-tester': {
+ enabled: true,
+ path: fixturesPath,
+ },
+ }
+};
diff --git a/test/func/fixtures/hermione/failed-describe.hermione.js b/test/func/fixtures/hermione/failed-describe.hermione.js
new file mode 100644
index 000000000..d7edb4ff1
--- /dev/null
+++ b/test/func/fixtures/hermione/failed-describe.hermione.js
@@ -0,0 +1,17 @@
+describe('failed describe', function() {
+ it('successfully passed test', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ assert.isTrue(true);
+ });
+
+ it('test without screenshot', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ await this.browser.assertView('header', 'header');
+ });
+
+ it('test with long error message', async function() {
+ throw new Error(`long_error_message ${'0123456789'.repeat(20)}\n message content`);
+ });
+});
diff --git a/test/func/fixtures/index.html b/test/func/fixtures/hermione/index.html
similarity index 100%
rename from test/func/fixtures/index.html
rename to test/func/fixtures/hermione/index.html
diff --git a/test/func/fixtures/hermione/screens/a5c1fda/chrome/header.png b/test/func/fixtures/hermione/screens/a5c1fda/chrome/header.png
new file mode 100644
index 000000000..4d02d9fb6
Binary files /dev/null and b/test/func/fixtures/hermione/screens/a5c1fda/chrome/header.png differ
diff --git a/test/func/fixtures/hermione/screens/eea1754/chrome/header.png b/test/func/fixtures/hermione/screens/eea1754/chrome/header.png
new file mode 100644
index 000000000..4d02d9fb6
Binary files /dev/null and b/test/func/fixtures/hermione/screens/eea1754/chrome/header.png differ
diff --git a/test/func/fixtures/hermione/success-describe.hermione.js b/test/func/fixtures/hermione/success-describe.hermione.js
new file mode 100644
index 000000000..5962aa1c7
--- /dev/null
+++ b/test/func/fixtures/hermione/success-describe.hermione.js
@@ -0,0 +1,13 @@
+describe('success describe', function() {
+ it('succesfully passed test', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ assert.isTrue(true);
+ });
+
+ it('test with screenshot', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ await this.browser.assertView('header', 'header');
+ });
+});
diff --git a/test/func/fixtures/.hermione.fixtures.js b/test/func/fixtures/plugins/.hermione.conf.js
similarity index 87%
rename from test/func/fixtures/.hermione.fixtures.js
rename to test/func/fixtures/plugins/.hermione.conf.js
index 4fe8579a5..6fe9d41af 100644
--- a/test/func/fixtures/.hermione.fixtures.js
+++ b/test/func/fixtures/plugins/.hermione.conf.js
@@ -1,18 +1,20 @@
'use strict';
+const {GRID_URL, CHROME_BINARY_PATH} = require('../../utils/constants');
global.assert = require('chai').assert;
const serverPort = 8080;
const fixturesPath = 'test/func/fixtures/report';
module.exports = {
- baseUrl: `http://localhost:${serverPort}/test/func/fixtures/index.html`,
+ gridUrl: GRID_URL,
+ baseUrl: `http://localhost:${serverPort}/test/func/fixtures/plugins/index.html`,
screenshotsDir: 'test/func/fixtures/screens',
sets: {
fixtures: {
- files: 'test/func/fixtures/**/*.hermione.js'
+ files: 'test/func/fixtures/plugins/**/*.hermione.js'
}
},
@@ -20,7 +22,11 @@ module.exports = {
chrome: {
windowSize: '1280x1024',
desiredCapabilities: {
- browserName: 'chrome'
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ args: ['headless', 'no-sandbox'],
+ binary: CHROME_BINARY_PATH,
+ }
}
}
},
@@ -33,7 +39,7 @@ module.exports = {
'html-reporter-tester': {
enabled: true,
path: fixturesPath,
- pluginsEnabled: false,
+ pluginsEnabled: true,
plugins: [
{
name: 'html-reporter-basic-plugin',
@@ -90,9 +96,5 @@ module.exports = {
}
]
},
- 'hermione-headless-chrome': {
- browserId: 'chrome',
- version: '77'
- }
}
};
diff --git a/test/func/fixtures/plugins/failed-describe.hermione.js b/test/func/fixtures/plugins/failed-describe.hermione.js
new file mode 100644
index 000000000..d7edb4ff1
--- /dev/null
+++ b/test/func/fixtures/plugins/failed-describe.hermione.js
@@ -0,0 +1,17 @@
+describe('failed describe', function() {
+ it('successfully passed test', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ assert.isTrue(true);
+ });
+
+ it('test without screenshot', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ await this.browser.assertView('header', 'header');
+ });
+
+ it('test with long error message', async function() {
+ throw new Error(`long_error_message ${'0123456789'.repeat(20)}\n message content`);
+ });
+});
diff --git a/test/func/html-reporter-plugins/.eslintrc.js b/test/func/fixtures/plugins/html-reporter-plugins/.eslintrc.js
similarity index 100%
rename from test/func/html-reporter-plugins/.eslintrc.js
rename to test/func/fixtures/plugins/html-reporter-plugins/.eslintrc.js
diff --git a/test/func/html-reporter-plugins/basic/lib/color-border.css b/test/func/fixtures/plugins/html-reporter-plugins/basic/lib/color-border.css
similarity index 100%
rename from test/func/html-reporter-plugins/basic/lib/color-border.css
rename to test/func/fixtures/plugins/html-reporter-plugins/basic/lib/color-border.css
diff --git a/test/func/html-reporter-plugins/basic/lib/color-border.jsx b/test/func/fixtures/plugins/html-reporter-plugins/basic/lib/color-border.jsx
similarity index 100%
rename from test/func/html-reporter-plugins/basic/lib/color-border.jsx
rename to test/func/fixtures/plugins/html-reporter-plugins/basic/lib/color-border.jsx
diff --git a/test/func/html-reporter-plugins/basic/package.json b/test/func/fixtures/plugins/html-reporter-plugins/basic/package.json
similarity index 100%
rename from test/func/html-reporter-plugins/basic/package.json
rename to test/func/fixtures/plugins/html-reporter-plugins/basic/package.json
diff --git a/test/func/html-reporter-plugins/basic/webpack.config.js b/test/func/fixtures/plugins/html-reporter-plugins/basic/webpack.config.js
similarity index 100%
rename from test/func/html-reporter-plugins/basic/webpack.config.js
rename to test/func/fixtures/plugins/html-reporter-plugins/basic/webpack.config.js
diff --git a/test/func/html-reporter-plugins/menu-bar/lib/menu-bar-item.css b/test/func/fixtures/plugins/html-reporter-plugins/menu-bar/lib/menu-bar-item.css
similarity index 100%
rename from test/func/html-reporter-plugins/menu-bar/lib/menu-bar-item.css
rename to test/func/fixtures/plugins/html-reporter-plugins/menu-bar/lib/menu-bar-item.css
diff --git a/test/func/html-reporter-plugins/menu-bar/lib/menu-bar-item.jsx b/test/func/fixtures/plugins/html-reporter-plugins/menu-bar/lib/menu-bar-item.jsx
similarity index 100%
rename from test/func/html-reporter-plugins/menu-bar/lib/menu-bar-item.jsx
rename to test/func/fixtures/plugins/html-reporter-plugins/menu-bar/lib/menu-bar-item.jsx
diff --git a/test/func/html-reporter-plugins/menu-bar/package.json b/test/func/fixtures/plugins/html-reporter-plugins/menu-bar/package.json
similarity index 100%
rename from test/func/html-reporter-plugins/menu-bar/package.json
rename to test/func/fixtures/plugins/html-reporter-plugins/menu-bar/package.json
diff --git a/test/func/html-reporter-plugins/menu-bar/webpack.config.js b/test/func/fixtures/plugins/html-reporter-plugins/menu-bar/webpack.config.js
similarity index 100%
rename from test/func/html-reporter-plugins/menu-bar/webpack.config.js
rename to test/func/fixtures/plugins/html-reporter-plugins/menu-bar/webpack.config.js
diff --git a/test/func/html-reporter-plugins/redux-with-server/lib/color-border.css b/test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/lib/color-border.css
similarity index 100%
rename from test/func/html-reporter-plugins/redux-with-server/lib/color-border.css
rename to test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/lib/color-border.css
diff --git a/test/func/html-reporter-plugins/redux-with-server/lib/color-border.jsx b/test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/lib/color-border.jsx
similarity index 100%
rename from test/func/html-reporter-plugins/redux-with-server/lib/color-border.jsx
rename to test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/lib/color-border.jsx
diff --git a/test/func/html-reporter-plugins/redux-with-server/middleware.js b/test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/middleware.js
similarity index 100%
rename from test/func/html-reporter-plugins/redux-with-server/middleware.js
rename to test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/middleware.js
diff --git a/test/func/html-reporter-plugins/redux-with-server/package.json b/test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/package.json
similarity index 100%
rename from test/func/html-reporter-plugins/redux-with-server/package.json
rename to test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/package.json
diff --git a/test/func/html-reporter-plugins/redux-with-server/webpack.config.js b/test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/webpack.config.js
similarity index 100%
rename from test/func/html-reporter-plugins/redux-with-server/webpack.config.js
rename to test/func/fixtures/plugins/html-reporter-plugins/redux-with-server/webpack.config.js
diff --git a/test/func/html-reporter-plugins/redux/lib/color-border.css b/test/func/fixtures/plugins/html-reporter-plugins/redux/lib/color-border.css
similarity index 100%
rename from test/func/html-reporter-plugins/redux/lib/color-border.css
rename to test/func/fixtures/plugins/html-reporter-plugins/redux/lib/color-border.css
diff --git a/test/func/html-reporter-plugins/redux/lib/color-border.jsx b/test/func/fixtures/plugins/html-reporter-plugins/redux/lib/color-border.jsx
similarity index 100%
rename from test/func/html-reporter-plugins/redux/lib/color-border.jsx
rename to test/func/fixtures/plugins/html-reporter-plugins/redux/lib/color-border.jsx
diff --git a/test/func/html-reporter-plugins/redux/package.json b/test/func/fixtures/plugins/html-reporter-plugins/redux/package.json
similarity index 100%
rename from test/func/html-reporter-plugins/redux/package.json
rename to test/func/fixtures/plugins/html-reporter-plugins/redux/package.json
diff --git a/test/func/html-reporter-plugins/redux/webpack.config.js b/test/func/fixtures/plugins/html-reporter-plugins/redux/webpack.config.js
similarity index 100%
rename from test/func/html-reporter-plugins/redux/webpack.config.js
rename to test/func/fixtures/plugins/html-reporter-plugins/redux/webpack.config.js
diff --git a/test/func/fixtures/plugins/index.html b/test/func/fixtures/plugins/index.html
new file mode 100644
index 000000000..412c348f3
--- /dev/null
+++ b/test/func/fixtures/plugins/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+
+ tag1
+ tag2
+ tag3
+
+
+
+
+
+
+
diff --git a/test/func/fixtures/plugins/success-describe.hermione.js b/test/func/fixtures/plugins/success-describe.hermione.js
new file mode 100644
index 000000000..5962aa1c7
--- /dev/null
+++ b/test/func/fixtures/plugins/success-describe.hermione.js
@@ -0,0 +1,13 @@
+describe('success describe', function() {
+ it('succesfully passed test', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ assert.isTrue(true);
+ });
+
+ it('test with screenshot', async function() {
+ await this.browser.url(this.browser.options.baseUrl);
+
+ await this.browser.assertView('header', 'header');
+ });
+});
diff --git a/test/func/fixtures/screens/a5c1fda/chrome/header.png b/test/func/fixtures/screens/a5c1fda/chrome/header.png
deleted file mode 100644
index 6f675add9..000000000
Binary files a/test/func/fixtures/screens/a5c1fda/chrome/header.png and /dev/null differ
diff --git a/test/func/fixtures/screens/eea1754/chrome/header.png b/test/func/fixtures/screens/eea1754/chrome/header.png
deleted file mode 100644
index 6f675add9..000000000
Binary files a/test/func/fixtures/screens/eea1754/chrome/header.png and /dev/null differ
diff --git a/test/func/fixtures/success-describe.hermione.js b/test/func/fixtures/success-describe.hermione.js
deleted file mode 100644
index d5c0876bf..000000000
--- a/test/func/fixtures/success-describe.hermione.js
+++ /dev/null
@@ -1,13 +0,0 @@
-describe('success describe', function() {
- it('succesfully passed test', function() {
- return this.browser
- .url('')
- .then(() => assert.isTrue(true));
- });
-
- it('test with screenshot', function() {
- return this.browser
- .url('')
- .assertView('header', 'header');
- });
-});
diff --git a/test/func/hermione-plugins/html-reporter-tester/index.js b/test/func/hermione-plugins/html-reporter-tester/index.js
deleted file mode 100644
index 96bcfe5de..000000000
--- a/test/func/hermione-plugins/html-reporter-tester/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'use strict';
-
-module.exports = require('../../../../hermione');
diff --git a/test/func/html-reporter-plugins/basic/plugin.js b/test/func/html-reporter-plugins/basic/plugin.js
deleted file mode 100644
index e3eb62a56..000000000
--- a/test/func/html-reporter-plugins/basic/plugin.js
+++ /dev/null
@@ -1,22 +0,0 @@
-__hermione_html_reporter_register_plugin__(function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=42)}([function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t){var n=e.exports={version:"2.6.9"};"number"==typeof __e&&(__e=n)},function(e,t,n){var r=n(10),o=n(30),i=n(15),u=Object.defineProperty;t.f=n(3)?Object.defineProperty:function(e,t,n){if(r(e),t=i(t,!0),r(n),o)try{return u(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){e.exports=!n(11)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(2),o=n(12);e.exports=n(3)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(56),o=n(17);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(22)("wks"),o=n(14),i=n(0).Symbol,u="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=u&&i[e]||(u?i:o)("Symbol."+e))}).store=r},function(e,t,n){var r=n(0),o=n(1),i=n(29),u=n(5),a=n(4),c=function(e,t,n){var f,s,l,p=e&c.F,d=e&c.G,y=e&c.S,v=e&c.P,h=e&c.B,m=e&c.W,b=d?o:o[t]||(o[t]={}),g=b.prototype,_=d?r:y?r[t]:(r[t]||{}).prototype;d&&(n=t);for(f in n)(s=!p&&_&&void 0!==_[f])&&a(b,f)||(l=s?_[f]:n[f],b[f]=d&&"function"!=typeof _[f]?n[f]:h&&s?i(l,r):m&&_[f]==l?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(l):v&&"function"==typeof l?i(Function.call,l):l,v&&((b.virtual||(b.virtual={}))[f]=l,e&c.R&&g&&!g[f]&&u(g,f,l)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){var r=n(6);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){e.exports=!0},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t,n){var r=n(6);e.exports=function(e,t){if(!r(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!r(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t){e.exports={}},function(e,t,n){var r=n(10),o=n(55),i=n(23),u=n(21)("IE_PROTO"),a=function(){},c=function(){var e,t=n(31)("iframe"),r=i.length;for(t.style.display="none",n(60).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write("