ui5-test-runner 1.1.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +32 -188
  2. package/index.js +47 -16
  3. package/package.json +28 -10
  4. package/src/add-test-pages.js +35 -0
  5. package/src/add-test-pages.spec.js +95 -0
  6. package/src/browser.spec.js +724 -0
  7. package/src/browsers.js +220 -59
  8. package/src/capabilities/index.js +194 -0
  9. package/src/capabilities/tests/basic/iframe.html +8 -0
  10. package/src/capabilities/tests/basic/index.html +12 -0
  11. package/src/capabilities/tests/basic/index.js +20 -0
  12. package/src/capabilities/tests/basic/ui5.html +24 -0
  13. package/src/capabilities/tests/dynamic-include/index.js +21 -0
  14. package/src/capabilities/tests/dynamic-include/mix.html +11 -0
  15. package/src/capabilities/tests/dynamic-include/one.html +11 -0
  16. package/src/capabilities/tests/dynamic-include/post.js +3 -0
  17. package/src/capabilities/tests/dynamic-include/test.js +1 -0
  18. package/src/capabilities/tests/dynamic-include/two.html +11 -0
  19. package/src/capabilities/tests/index.js +16 -0
  20. package/src/capabilities/tests/local-storage/index.html +16 -0
  21. package/src/capabilities/tests/local-storage/index.js +21 -0
  22. package/src/capabilities/tests/screenshot/index.html +13 -0
  23. package/src/capabilities/tests/screenshot/index.js +18 -0
  24. package/src/capabilities/tests/scripts/index.js +50 -0
  25. package/src/capabilities/tests/scripts/qunit.html +22 -0
  26. package/src/capabilities/tests/scripts/testsuite.html +10 -0
  27. package/src/capabilities/tests/scripts/testsuite.js +8 -0
  28. package/src/capabilities/tests/timeout/index.html +21 -0
  29. package/src/capabilities/tests/timeout/index.js +19 -0
  30. package/src/capabilities/tests/traces/index.html +18 -0
  31. package/src/capabilities/tests/traces/index.js +81 -0
  32. package/src/cors.js +1 -1
  33. package/src/cors.spec.js +41 -0
  34. package/src/coverage.js +30 -18
  35. package/src/coverage.spec.js +79 -0
  36. package/src/csv-reader.js +36 -0
  37. package/src/csv-reader.spec.js +42 -0
  38. package/src/csv-writer.js +52 -0
  39. package/src/csv-writer.spec.js +77 -0
  40. package/src/defaults/browser.js +144 -0
  41. package/src/defaults/jsdom/compatibility.js +95 -0
  42. package/src/defaults/jsdom/debug.js +23 -0
  43. package/src/defaults/jsdom/resource-loader.js +43 -0
  44. package/src/defaults/jsdom/sap.ui.test.matchers.visible.js +39 -0
  45. package/src/defaults/jsdom.js +64 -0
  46. package/src/defaults/junit-xml-report.js +64 -0
  47. package/src/defaults/puppeteer.js +111 -0
  48. package/src/defaults/report/common.js +38 -0
  49. package/src/defaults/report/default.html +84 -0
  50. package/src/defaults/report/main.js +44 -0
  51. package/src/defaults/report/progress.js +49 -0
  52. package/src/defaults/report/styles.css +66 -0
  53. package/src/defaults/report.js +69 -0
  54. package/src/defaults/selenium-webdriver/chrome.js +38 -0
  55. package/src/defaults/selenium-webdriver/edge.js +25 -0
  56. package/src/defaults/selenium-webdriver/firefox.js +31 -0
  57. package/src/defaults/selenium-webdriver.js +138 -0
  58. package/src/endpoints.js +70 -124
  59. package/src/error.js +52 -0
  60. package/src/error.spec.js +17 -0
  61. package/src/get-job-progress.js +69 -0
  62. package/src/get-job-progress.spec.js +175 -0
  63. package/src/inject/post.js +96 -0
  64. package/src/inject/post.spec.js +147 -0
  65. package/src/inject/qunit-hooks.js +6 -21
  66. package/src/inject/qunit-intercept.js +30 -0
  67. package/src/inject/qunit-redirect.js +15 -7
  68. package/src/job-mode.js +45 -0
  69. package/src/job.js +254 -108
  70. package/src/job.spec.js +413 -0
  71. package/src/npm.js +73 -0
  72. package/src/npm.spec.js +98 -0
  73. package/src/options.js +73 -0
  74. package/src/options.spec.js +125 -0
  75. package/src/output.js +450 -131
  76. package/src/qunit-hooks.js +116 -0
  77. package/src/qunit-hooks.spec.js +687 -0
  78. package/src/report.js +42 -0
  79. package/src/reserve.js +3 -4
  80. package/src/simulate.spec.js +437 -0
  81. package/src/symbols.js +8 -0
  82. package/src/tests.js +127 -84
  83. package/src/timeout.spec.js +39 -0
  84. package/src/tools.js +111 -4
  85. package/src/tools.spec.js +90 -0
  86. package/src/ui5.js +3 -3
  87. package/src/unhandled.js +6 -6
  88. package/src/unhandled.spec.js +63 -0
  89. package/defaults/chromium.js +0 -62
  90. package/src/progress.html +0 -71
  91. package/src/proxies.js +0 -8
  92. package/src/report.html +0 -202
  93. /package/{defaults → src/defaults}/nyc.json +0 -0
@@ -0,0 +1,84 @@
1
+ <html>
2
+ <head>
3
+ <title>ui5-test-runner</title>
4
+ <link rel="stylesheet" href="/_/report/styles.css">
5
+ <script src="/_/punyexpr.js"></script>
6
+ <script src="/_/punybind.js"></script>
7
+ <script src="/_/report/common.js"></script>
8
+ <script src="/_/report/main.js"></script>
9
+ </head>
10
+ <body>
11
+ <div {{if}}="!(qunitPage || qunitTest)">
12
+ <h1>{{ status || 'Test report' }}</h1>
13
+ <div {{if}}="end === undefined" class="elapsed">In progress since {{ elapsed(start) }}</div>
14
+ <div {{else}} class="elapsed">Duration : {{ elapsed(start, end) }}</div>
15
+ <table style="visibility: {{ testPageUrls.length > 0 ? 'visible' : 'hidden' }};">
16
+ <tr>
17
+ <th>&nbsp;</th>
18
+ <th class="status" style="width: 10rem;"><div><span>Status</span></div></th>
19
+ <th class="count">Tests</th>
20
+ <th class="count">Passed</th>
21
+ <th class="count">Failed</th>
22
+ <th class="elapsed">Elapsed</th>
23
+ </tr>
24
+ <tr {{for}}="url of testPageUrls">
25
+ <td class="truncated">
26
+ <span {{if}}="qunitPages === undefined || !qunitPages[url]">{{ url }}</span>
27
+ <a {{else}} href="#{{ qunitPages[url].id }}">{{ url }}</a>
28
+ </td>
29
+ <td>
30
+ <span {{if}}="!qunitPages[url]">-</span>
31
+ <span {{elseif}}="qunitPages[url].failed">&#10060;</span>
32
+ <span {{elseif}}="qunitPages[url].end">&#10004;&#65039;</span>
33
+ <span {{if}}="!qunitPages[url].end">
34
+ <progress max="{{ qunitPages[url].count }}" value="{{ qunitPages[url].failed + qunitPages[url].passed }}"></progress>
35
+ </span>
36
+ </td>
37
+ <td>{{ qunitPages[url] ? qunitPages[url].count : '-' }}</td>
38
+ <td>{{ qunitPages[url] ? qunitPages[url].passed : '-' }}</td>
39
+ <td>{{ qunitPages[url] ? qunitPages[url].failed : '-' }}</td>
40
+ <td>
41
+ <span {{if}}="!qunitPages[url]">-</span>
42
+ <span {{elseif}}="qunitPages[url].end === undefined">{{ elapsed(qunitPages[url].start) }}</span>
43
+ <span {{else}}>{{ elapsed(qunitPages[url].start, qunitPages[url].end) }}</span>
44
+ </td>
45
+ </tr>
46
+ </table>
47
+ </div>
48
+ <div {{if}}="qunitPage">
49
+ <h1 class="truncated">{{ qunitPage.url }}</h1>
50
+ <a href="#">&#9204; back to report</a>
51
+ <div {{if}}="qunitPage.end === undefined" class="elapsed">In progress since {{ elapsed(qunitPage.start) }}</div>
52
+ <div {{else}} class="elapsed">Duration : {{ elapsed(qunitPage.start, qunitPage.end) }}</div>
53
+ <div {{for}}="module of qunitPage.modules">
54
+ <h2>{{ module.name }}</h2>
55
+ <div {{for}}="test of module.tests">
56
+ <a {{if}}="!test.skip" href="#{{ qunitPage.id }}-{{ test.testId }}">{{ test.name }}</a>
57
+ <span {{else}}>{{ test.name }}</span>
58
+ <span {{if}}="test.skip">&#9208;&#65039;</span>
59
+ <span {{elseif}}="!test.end" class="elapsed">{{ elapsed(test.start) }}</span>
60
+ <span {{elseif}}="test.report && !test.report.failed">&#10004;&#65039; {{ elapsed(test.start, test.end) }}</span>
61
+ <span {{elseif}}="test.report">&#10060; {{ elapsed(test.start, test.end) }}</span>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ <div {{elseif}}="qunitTest">
66
+ <h1 class="truncated">{{ qunitTest.url }}</h1>
67
+ <a href="#">&#9204; back to report</a>
68
+ <h2>{{ qunitTest.module }}</h2>
69
+ <a href="#{{ qunitTest.pageId }}">&#9204; back to page</a>
70
+ <h3>{{ qunitTest.name }}
71
+ <span {{if}}="qunitTest.report && qunitTest.report.passed">&#10004;&#65039;</span>
72
+ <span {{elseif}}="qunitTest.report">&#10060;</span>
73
+ </h3>
74
+ <div {{if}}="qunitTest.end === undefined" class="elapsed">In progress since {{ elapsed(qunitTest.start) }}</div>
75
+ <div {{else}} class="elapsed">Duration : {{ elapsed(qunitTest.start, qunitTest.end) }}</div>
76
+ <div {{for}}="log of qunitTest.logs">
77
+ <pre {{if}}="log.result">&#10004;&#65039; {{ log.message }}</pre>
78
+ <pre {{else}}>&#10060; {{ log.message }}</pre>
79
+ <img {{if}}="log.screenshot" loading="lazy" class="log" src="{{ qunitTest.pageId }}/{{ log.screenshot }}" alt="Copy folder '{{ qunitTest.pageId }}' from the job report">
80
+ </div>
81
+ </div>
82
+ <div style="display: {{ disconnected ? 'block' : 'none' }};">&#10060; Disconnected</div>
83
+ </body>
84
+ </html>
@@ -0,0 +1,44 @@
1
+ /* global report, job */
2
+ report.ready.then(update => {
3
+ const hashChange = () => {
4
+ const [, pageId, testId] = location.hash.match(/#?([^-]*)(?:-(.*))?/)
5
+ let [qunitPage, qunitTest] = [null, null]
6
+ if (pageId) {
7
+ const url = Object.keys(job.qunitPages).find(pageUrl => job.qunitPages[pageUrl].id === pageId)
8
+ if (!url) {
9
+ return
10
+ }
11
+ qunitPage = { url, ...job.qunitPages[url] }
12
+ if (testId) {
13
+ let test
14
+ let moduleName
15
+ qunitPage.modules.every(module => module.tests.every(candidate => {
16
+ if (candidate.testId === testId) {
17
+ moduleName = module.name
18
+ test = candidate
19
+ return false
20
+ }
21
+ return true
22
+ }))
23
+ qunitPage = null
24
+ if (test) {
25
+ qunitTest = {
26
+ url,
27
+ pageId,
28
+ module: moduleName,
29
+ ...test
30
+ }
31
+ }
32
+ }
33
+ }
34
+ update({
35
+ ...job,
36
+ qunitPage,
37
+ qunitTest,
38
+ elapsed: report.elapsed
39
+ })
40
+ }
41
+
42
+ window.addEventListener('hashchange', hashChange)
43
+ hashChange()
44
+ })
@@ -0,0 +1,49 @@
1
+ (function () {
2
+ /* global report */
3
+
4
+ report.ready.then(update => {
5
+ let lastState = {}
6
+
7
+ async function refresh () {
8
+ const [, page, test] = location.hash.match(/#?([^-]*)(?:-(.*))?/)
9
+ let url = '/_/progress'
10
+ if (page) {
11
+ url += `?page=${page}`
12
+ if (test) {
13
+ url += `&test=${test}`
14
+ }
15
+ }
16
+ let json
17
+ try {
18
+ const response = await fetch(url)
19
+ json = await response.json()
20
+ } catch (e) {
21
+ update({
22
+ ...lastState,
23
+ disconnected: true
24
+ })
25
+ return
26
+ }
27
+ if (test) {
28
+ lastState = {
29
+ qunitTest: json
30
+ }
31
+ } else if (page) {
32
+ lastState = {
33
+ qunitPage: json
34
+ }
35
+ } else {
36
+ lastState = {
37
+ ...json
38
+ }
39
+ }
40
+ update({
41
+ ...lastState,
42
+ disconnected: false,
43
+ elapsed: report.elapsed
44
+ })
45
+ setTimeout(refresh, 250)
46
+ }
47
+ refresh()
48
+ })
49
+ }())
@@ -0,0 +1,66 @@
1
+ body {
2
+ font-family: "Segoe UI", Arial, sans-serif;
3
+ }
4
+
5
+ h1 {
6
+ margin-bottom: 0;
7
+ }
8
+
9
+ h2 {
10
+ margin-bottom: 0;
11
+ }
12
+
13
+ h3 {
14
+ margin-bottom: 0;
15
+ }
16
+
17
+ progress {
18
+ width: 5rem;
19
+ }
20
+
21
+ th {
22
+ text-align: left;
23
+ }
24
+
25
+ th.count {
26
+ width: 5rem;
27
+ }
28
+
29
+ th.elapsed {
30
+ width: 6rem;
31
+ }
32
+
33
+ th.status {
34
+ width: 10rem;
35
+ }
36
+
37
+ a, a:hover {
38
+ color: black;
39
+ text-decoration: none;
40
+ }
41
+
42
+ a:hover {
43
+ text-decoration: underline;
44
+ text-decoration-style: dotted;
45
+ }
46
+
47
+ table {
48
+ table-layout: fixed;
49
+ width: 100%;
50
+ }
51
+
52
+ .truncated {
53
+ overflow: hidden;
54
+ text-overflow: ellipsis;
55
+ white-space: nowrap;
56
+ direction: rtl;
57
+ text-align: left;
58
+ }
59
+
60
+ img.log {
61
+ width: 50%;
62
+ }
63
+
64
+ img.log:hover {
65
+ width: unset;
66
+ }
@@ -0,0 +1,69 @@
1
+ 'use strict'
2
+
3
+ const { join } = require('path')
4
+ const { readFile, writeFile } = require('fs').promises
5
+ const [,, reportDir] = process.argv
6
+
7
+ const defaultDir = join(__dirname, 'report')
8
+
9
+ async function readDefault (name) {
10
+ return (await readFile(join(defaultDir, name))).toString()
11
+ }
12
+
13
+ async function readDependency (name) {
14
+ return (await readFile(join(__dirname, '../../node_modules', name, 'dist', `${name}.js`))).toString()
15
+ }
16
+
17
+ function minifyJs (src) {
18
+ return src
19
+ .replace(/\/\*.*\*\//g, '')
20
+ .replace(/\{\r?\n\s*/g, '{')
21
+ .replace(/\r?\n\s*\}/g, '}')
22
+ .replace(/,?\r?\n\s*\.?/g, match => {
23
+ let result = ''
24
+ if (match.startsWith(',')) {
25
+ result = ','
26
+ }
27
+ if (match.endsWith('.')) {
28
+ result += '.'
29
+ }
30
+ return result || ';'
31
+ })
32
+ }
33
+
34
+ async function main () {
35
+ const html = await readDefault('default.html')
36
+ const styles = (await readDefault('styles.css'))
37
+ .replace(/\{\r?\n\s+/g, '{')
38
+ .replace(/\}(\r?\n)+/g, '} ')
39
+ .replace(/;\r?\n\s*/g, ';')
40
+ .replace(/(:|,)\s*/g, (_, c) => c)
41
+
42
+ const punyexpr = await readDependency('punyexpr')
43
+ const punybind = await readDependency('punybind')
44
+ const common = minifyJs(await readDefault('common.js'))
45
+ const main = minifyJs(await readDefault('main.js'))
46
+
47
+ const job = (await readFile(join(reportDir, 'job.js'))).toString()
48
+ .replace(/(\{|,|\[)\r?\n\s*/g, (_, c) => c)
49
+ .replace(/\r?\n\s*(\}|\])/g, (_, c) => c)
50
+ .replace(/": "/g, '":"')
51
+
52
+ return await writeFile(join(reportDir, 'report.html'), html
53
+ .replace(/(>|\}\})\r?\n\s*</g, (_, c) => `${c}<`)
54
+ .replace('<link rel="stylesheet" href="/_/report/styles.css">', `<style>${styles}</style>`)
55
+ .replace('<script src="/_/punyexpr.js"></script>', `<script>${punyexpr}</script>`)
56
+ .replace('<script src="/_/punybind.js"></script>', `<script>${punybind}</script>`)
57
+ .replace('<script src="/_/report/common.js"></script>', `<script>${common}</script>`)
58
+ .replace('<script src="/_/report/main.js"></script>', `<script>const module={};${job};const job=module.exports;${main}</script>`)
59
+ )
60
+ }
61
+
62
+ main()
63
+ .catch(reason => {
64
+ console.error(reason)
65
+ return -1
66
+ })
67
+ .then((code = 0) => {
68
+ process.exit(code)
69
+ })
@@ -0,0 +1,38 @@
1
+ const { join } = require('path')
2
+
3
+ module.exports = async ({
4
+ seleniumWebdriver,
5
+ settings,
6
+ options,
7
+ loggingPreferences
8
+ }) => {
9
+ const { Browser, Builder } = seleniumWebdriver
10
+ const chrome = require(join(settings.modules['selenium-webdriver'], 'chrome'))
11
+
12
+ const chromeOptions = new chrome.Options()
13
+ chromeOptions.excludeSwitches('enable-logging')
14
+ if (!options.visible) {
15
+ chromeOptions.addArguments('headless')
16
+ }
17
+ chromeOptions.addArguments('start-maximized')
18
+ chromeOptions.addArguments('disable-extensions')
19
+ chromeOptions.setLoggingPrefs(loggingPreferences)
20
+ if (options.binary) {
21
+ chromeOptions.setBinary(options.binary)
22
+ }
23
+
24
+ const builder = new Builder()
25
+ .forBrowser(Browser.CHROME)
26
+ .setChromeOptions(chromeOptions)
27
+
28
+ if (options.server) {
29
+ builder.usingServer(options.server)
30
+ }
31
+
32
+ const driver = await builder.build()
33
+ driver.__console__ = true
34
+ driver.__addScript__ = async function (source) {
35
+ return await driver.sendDevToolsCommand('Page.addScriptToEvaluateOnNewDocument', { source })
36
+ }
37
+ return driver
38
+ }
@@ -0,0 +1,25 @@
1
+ const { join } = require('path')
2
+
3
+ module.exports = async ({
4
+ seleniumWebdriver,
5
+ settings,
6
+ options,
7
+ loggingPreferences,
8
+ $capabilities
9
+ }) => {
10
+ const { Browser, Builder } = seleniumWebdriver
11
+ const edge = require(join(settings.modules['selenium-webdriver'], 'edge'))
12
+
13
+ const edgeOptions = new edge.Options()
14
+ edgeOptions.setLoggingPrefs(loggingPreferences)
15
+
16
+ const builder = new Builder()
17
+ .forBrowser(Browser.EDGE)
18
+ .setEdgeOptions(edgeOptions)
19
+
20
+ if (options.server) {
21
+ builder.usingServer(options.server)
22
+ }
23
+
24
+ return await builder.build()
25
+ }
@@ -0,0 +1,31 @@
1
+ const { join } = require('path')
2
+
3
+ module.exports = async ({
4
+ seleniumWebdriver,
5
+ settings,
6
+ options,
7
+ loggingPreferences,
8
+ $capabilities
9
+ }) => {
10
+ const { Browser, Builder } = seleniumWebdriver
11
+ const firefox = require(join(settings.modules['selenium-webdriver'], 'firefox'))
12
+
13
+ const firefoxOptions = new firefox.Options()
14
+ if (!options.visible) {
15
+ firefoxOptions.headless = true
16
+ }
17
+ firefoxOptions.setLoggingPrefs(loggingPreferences)
18
+ if (options.binary) {
19
+ firefoxOptions.setBinary(options.binary)
20
+ }
21
+
22
+ const builder = new Builder()
23
+ .forBrowser(Browser.FIREFOX)
24
+ .setFirefoxOptions(firefoxOptions)
25
+
26
+ if (options.server) {
27
+ builder.usingServer(options.server)
28
+ }
29
+
30
+ return await builder.build()
31
+ }
@@ -0,0 +1,138 @@
1
+ 'use strict'
2
+
3
+ const { InvalidArgumentError } = require('commander')
4
+ const { url } = require('../options')
5
+ const { writeFile } = require('fs/promises')
6
+
7
+ let logging
8
+ let driver
9
+
10
+ function browser (value, defaultValue) {
11
+ if (value === undefined) {
12
+ return 'chrome'
13
+ }
14
+ if (!['chrome', 'firefox', 'edge'].includes(value)) {
15
+ throw new InvalidArgumentError('Browser name')
16
+ }
17
+ return value
18
+ }
19
+
20
+ async function buildDriver (settings, options) {
21
+ const seleniumWebdriver = require(settings.modules['selenium-webdriver'])
22
+
23
+ logging = seleniumWebdriver.logging
24
+ logging.getLogger(logging.Type.BROWSER).setLevel(logging.Level.ALL)
25
+
26
+ const loggingPreferences = new logging.Preferences()
27
+ loggingPreferences.setLevel(logging.Type.BROWSER, logging.Level.ALL)
28
+
29
+ driver = await require('./selenium-webdriver/' + options.browser)({
30
+ seleniumWebdriver,
31
+ settings,
32
+ options,
33
+ loggingPreferences
34
+ })
35
+ }
36
+
37
+ require('./browser')({
38
+ metadata: {
39
+ name: 'selenium-webdriver',
40
+ options: [
41
+ ['-b, --browser <name>', 'Browser driver', browser, 'chrome'],
42
+ ['--visible [flag]', 'Show the browser', false],
43
+ ['-s, --server <server>', 'Selenium server URL', url],
44
+ ['--binary <binary>', 'Binary path']
45
+ ]
46
+ },
47
+
48
+ async capabilities ({ settings, options }) {
49
+ const capabilities = {
50
+ modules: ['selenium-webdriver'],
51
+ screenshot: '.png',
52
+ scripts: false,
53
+ traces: []
54
+ }
55
+ if (!settings.modules) {
56
+ return {
57
+ ...capabilities,
58
+ 'probe-with-modules': true
59
+ }
60
+ }
61
+ await buildDriver(settings, options)
62
+ if (driver.__console__) {
63
+ capabilities.traces.push('console')
64
+ }
65
+ if (driver.__network__) {
66
+ capabilities.traces.push('network')
67
+ }
68
+ if (driver.__addScript__) {
69
+ capabilities.scripts = true
70
+ }
71
+ return capabilities
72
+ },
73
+
74
+ async screenshot ({ filename }) {
75
+ if (driver) {
76
+ const data = await driver.takeScreenshot()
77
+ await writeFile(filename, data.replace(/^data:image\/png;base64,/, ''), {
78
+ encoding: 'base64'
79
+ })
80
+ return true
81
+ }
82
+ },
83
+
84
+ async flush ({
85
+ settings,
86
+ consoleWriter
87
+ }) {
88
+ if (driver && settings.capabilities.traces.includes('console')) {
89
+ const logs = await driver.manage().logs().get(logging.Type.BROWSER)
90
+ const logLevelMapping = {
91
+ INFO: 'log',
92
+ WARNING: 'warning',
93
+ SEVERE: 'error'
94
+ }
95
+ if (logs.length) {
96
+ consoleWriter.append(logs.map(({ timestamp, message, level }) => {
97
+ return {
98
+ timestamp,
99
+ type: logLevelMapping[level.toString()],
100
+ text: message
101
+ }
102
+ }))
103
+ }
104
+ }
105
+ },
106
+
107
+ async beforeExit () {
108
+ if (driver) {
109
+ await driver.quit()
110
+ }
111
+ },
112
+
113
+ async run ({
114
+ settings,
115
+ options
116
+ }) {
117
+ await buildDriver(settings, options)
118
+
119
+ const { url, scripts } = settings
120
+
121
+ if (scripts && scripts.length) {
122
+ for await (const script of scripts) {
123
+ await driver.__addScript__(script)
124
+ }
125
+ }
126
+
127
+ await driver.get(url)
128
+ },
129
+
130
+ async error ({ error: e }) {
131
+ if (e.name === 'SessionNotCreatedError') {
132
+ console.error(e.message)
133
+ } else {
134
+ console.error(e)
135
+ }
136
+ console.error('Please check https://www.npmjs.com/package/selenium-webdriver#installation for browser driver')
137
+ }
138
+ })