wdio-mediawiki 2.4.0 → 2.6.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.
- package/Api.js +1 -1
- package/BlankPage.js +3 -1
- package/CreateAccountPage.js +51 -7
- package/LoginPage.js +35 -6
- package/Page.js +13 -5
- package/README.md +7 -6
- package/RunJobs.js +18 -20
- package/Util.js +43 -9
- package/index.js +7 -9
- package/package.json +2 -5
- package/specs/BlankPage.js +3 -4
- package/wdio-defaults.conf.js +32 -12
package/Api.js
CHANGED
package/BlankPage.js
CHANGED
package/CreateAccountPage.js
CHANGED
|
@@ -1,20 +1,64 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Page = require( './Page' );
|
|
4
|
+
const Util = require( 'wdio-mediawiki/Util' );
|
|
4
5
|
|
|
5
6
|
class CreateAccountPage extends Page {
|
|
6
|
-
get username() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
get
|
|
7
|
+
get username() {
|
|
8
|
+
return $( '#wpName2' );
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get password() {
|
|
12
|
+
return $( '#wpPassword2' );
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get confirmPassword() {
|
|
16
|
+
return $( '#wpRetype' );
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get create() {
|
|
20
|
+
return $( '#wpCreateaccount' );
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get heading() {
|
|
24
|
+
return $( '#firstHeading' );
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get tempPasswordInput() {
|
|
28
|
+
return $( '#wpCreateaccountMail' );
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get reasonInput() {
|
|
32
|
+
return $( '#wpReason' );
|
|
33
|
+
}
|
|
11
34
|
|
|
12
|
-
open() {
|
|
13
|
-
super.openTitle( 'Special:CreateAccount' );
|
|
35
|
+
async open() {
|
|
36
|
+
await super.openTitle( 'Special:CreateAccount' );
|
|
14
37
|
}
|
|
15
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Navigate to Special:CreateAccount, then fill out and submit the account creation form.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} username
|
|
43
|
+
* @param {string} password
|
|
44
|
+
* @return {Promise<void>}
|
|
45
|
+
*/
|
|
16
46
|
async createAccount( username, password ) {
|
|
17
47
|
await this.open();
|
|
48
|
+
await this.submitForm( username, password );
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Fill out and submit the account creation form on Special:CreateAccount.
|
|
53
|
+
* The browser is assumed to have already navigated to this page.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} username
|
|
56
|
+
* @param {string} password
|
|
57
|
+
* @return {Promise<void>}
|
|
58
|
+
*/
|
|
59
|
+
async submitForm( username, password ) {
|
|
60
|
+
await Util.waitForModuleState( 'mediawiki.special.createaccount', 'ready', 10000 );
|
|
61
|
+
|
|
18
62
|
await this.username.setValue( username );
|
|
19
63
|
await this.password.setValue( password );
|
|
20
64
|
await this.confirmPassword.setValue( password );
|
package/LoginPage.js
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
|
+
// This file is used at Selenium/Explanation/Page object pattern
|
|
2
|
+
// https://www.mediawiki.org/wiki/Selenium/Explanation/Page_object_pattern
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
6
|
const Page = require( './Page' );
|
|
4
7
|
|
|
5
8
|
class LoginPage extends Page {
|
|
6
|
-
get username() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
get username() {
|
|
10
|
+
return $( '#wpName1' );
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get password() {
|
|
14
|
+
return $( '#wpPassword1' );
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get loginButton() {
|
|
18
|
+
return $( '#wpLoginAttempt' );
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get userPage() {
|
|
22
|
+
return $( '#pt-userpage' );
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async open() {
|
|
26
|
+
await super.openTitle( 'Special:UserLogin' );
|
|
27
|
+
}
|
|
10
28
|
|
|
11
|
-
|
|
12
|
-
|
|
29
|
+
async getActualUsername() {
|
|
30
|
+
return browser.execute( () => mw.config.get( 'wgUserName' ) );
|
|
13
31
|
}
|
|
14
32
|
|
|
15
33
|
async login( username, password ) {
|
|
@@ -17,6 +35,17 @@ class LoginPage extends Page {
|
|
|
17
35
|
await this.username.setValue( username );
|
|
18
36
|
await this.password.setValue( password );
|
|
19
37
|
await this.loginButton.click();
|
|
38
|
+
await browser.waitUntil(
|
|
39
|
+
async () => await browser.execute(
|
|
40
|
+
( expectedUsername ) => typeof mw !== 'undefined' &&
|
|
41
|
+
mw.config.get( 'wgUserName' ) === expectedUsername,
|
|
42
|
+
username
|
|
43
|
+
),
|
|
44
|
+
{
|
|
45
|
+
timeout: 15000,
|
|
46
|
+
timeoutMsg: 'Cannot submit login form'
|
|
47
|
+
}
|
|
48
|
+
);
|
|
20
49
|
}
|
|
21
50
|
|
|
22
51
|
async loginAdmin() {
|
package/Page.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const querystring = require( 'querystring' );
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Based on
|
|
6
|
+
* Based on https://webdriver.io/docs/pageobjects
|
|
7
7
|
*/
|
|
8
8
|
class Page {
|
|
9
9
|
|
|
@@ -11,20 +11,28 @@ class Page {
|
|
|
11
11
|
* Navigate the browser to a given page.
|
|
12
12
|
*
|
|
13
13
|
* @since 1.0.0
|
|
14
|
-
* @see <
|
|
14
|
+
* @see <https://webdriver.io/docs/api/browser/url>
|
|
15
15
|
* @param {string} title Page title
|
|
16
16
|
* @param {Object} [query] Query parameter
|
|
17
17
|
* @param {string} [fragment] Fragment parameter
|
|
18
|
-
* @return {void}
|
|
18
|
+
* @return {Promise<void>}
|
|
19
19
|
*/
|
|
20
20
|
async openTitle( title, query = {}, fragment = '' ) {
|
|
21
|
-
const config = Object.assign( browser.config || {}, browser.options || {} );
|
|
22
21
|
query.title = title;
|
|
23
22
|
await browser.url(
|
|
24
|
-
config.baseUrl + '/index.php?' +
|
|
23
|
+
browser.config.baseUrl + '/index.php?' +
|
|
25
24
|
querystring.stringify( query ) +
|
|
26
25
|
( fragment ? ( '#' + fragment ) : '' )
|
|
27
26
|
);
|
|
27
|
+
// Wait for the page to be fully loaded. TODO: This can be replaced by the `wait` option to
|
|
28
|
+
// browser.url in webdriverio 9 (T363704).
|
|
29
|
+
await browser.waitUntil(
|
|
30
|
+
() => browser.execute( () => document.readyState === 'complete' ),
|
|
31
|
+
{
|
|
32
|
+
timeout: 10 * 1000,
|
|
33
|
+
timeoutMsg: 'Page did not load in time'
|
|
34
|
+
}
|
|
35
|
+
);
|
|
28
36
|
}
|
|
29
37
|
}
|
|
30
38
|
|
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# wdio-mediawiki
|
|
2
2
|
|
|
3
|
-
A plugin for [WebdriverIO](
|
|
3
|
+
A plugin for [WebdriverIO](https://webdriver.io) providing utilities to simplify testing of MediaWiki features.
|
|
4
4
|
|
|
5
5
|
## Getting Started
|
|
6
6
|
|
|
7
7
|
### Page
|
|
8
8
|
|
|
9
|
-
The `Page` class is a base class for following the [Page Objects Pattern](
|
|
9
|
+
The `Page` class is a base class for following the [Page Objects Pattern](https://webdriver.io/docs/pageobjects).
|
|
10
10
|
|
|
11
11
|
* `openTitle( title [, Object query [, string fragment ] ] )`
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ See [BlankPage](./BlankPage.js) and [specs/BlankPage](./specs/BlankPage.js) for
|
|
|
17
17
|
|
|
18
18
|
### Api
|
|
19
19
|
|
|
20
|
-
Utilities to interact with the MediaWiki API. Uses the [mwbot](https://github.com/
|
|
20
|
+
Utilities to interact with the MediaWiki API. Uses the [mwbot](https://github.com/gesinn-it-pub/mwbot) library.
|
|
21
21
|
|
|
22
22
|
Actions are performed logged-in using `browser.config.mwUser` and `browser.config.mwPwd`,
|
|
23
23
|
which typically come from `MEDIAWIKI_USER` and `MEDIAWIKI_PASSWORD` environment variables.
|
|
@@ -46,11 +46,12 @@ making assertions that depend on its outcome.
|
|
|
46
46
|
`Util` is a collection of popular utility methods.
|
|
47
47
|
|
|
48
48
|
* `getTestString([ string prefix ])`
|
|
49
|
+
* `isTargetNotWikitext(string target)`
|
|
49
50
|
* `waitForModuleState(string moduleName [, string moduleStatus [, number timeout ] ])`
|
|
50
51
|
|
|
51
52
|
## Versioning
|
|
52
53
|
|
|
53
|
-
This package follows [Semantic Versioning guidelines](https://semver.org
|
|
54
|
+
This package follows [Semantic Versioning guidelines](https://semver.org) for its releases. In
|
|
54
55
|
particular, its major version must be bumped when compatibility is removed for a previous of
|
|
55
56
|
MediaWiki.
|
|
56
57
|
|
|
@@ -65,11 +66,11 @@ co-exists with its deprecated equivalent for at least one release.
|
|
|
65
66
|
|
|
66
67
|
## Issue tracker
|
|
67
68
|
|
|
68
|
-
Please report issues to [Phabricator](https://phabricator.wikimedia.org/tag/mediawiki-core-tests
|
|
69
|
+
Please report issues to [Phabricator](https://phabricator.wikimedia.org/tag/mediawiki-core-tests).
|
|
69
70
|
|
|
70
71
|
## Contributing
|
|
71
72
|
|
|
72
73
|
This module is maintained in the MediaWiki core repository and published from there as a
|
|
73
74
|
package to npmjs.org. To simplify development and to ensure changes are verified
|
|
74
75
|
automatically, MediaWiki core itself uses this module directly from the working copy
|
|
75
|
-
using [npm Local Paths](https://docs.npmjs.com/
|
|
76
|
+
using [npm Local Paths](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#local-paths).
|
package/RunJobs.js
CHANGED
|
@@ -6,7 +6,7 @@ const MAINPAGE_REQUESTS_MAX_RUNS = 10; // (arbitrary) safe-guard against endless
|
|
|
6
6
|
|
|
7
7
|
function getJobCount() {
|
|
8
8
|
const bot = new MWBot( {
|
|
9
|
-
apiUrl: `${browser.config.baseUrl}/api.php`
|
|
9
|
+
apiUrl: `${ browser.config.baseUrl }/api.php`
|
|
10
10
|
} );
|
|
11
11
|
return bot.request( {
|
|
12
12
|
action: 'query',
|
|
@@ -16,27 +16,27 @@ function getJobCount() {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function log( message ) {
|
|
19
|
-
process.stdout.write( `RunJobs ${message}\n` );
|
|
19
|
+
process.stdout.write( `RunJobs ${ message }\n` );
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function runThroughMainPageRequests( runCount = 1 ) {
|
|
23
23
|
const page = new Page();
|
|
24
|
-
log( `through requests to the main page (run ${runCount}).` );
|
|
24
|
+
log( `through requests to the main page (run ${ runCount }).` );
|
|
25
25
|
|
|
26
|
-
page.openTitle( '' )
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
return page.openTitle( '' ).then(
|
|
27
|
+
() => getJobCount().then( ( jobCount ) => {
|
|
28
|
+
if ( jobCount === 0 ) {
|
|
29
|
+
log( 'found no more queued jobs.' );
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
log( `detected ${ jobCount } more queued job(s).` );
|
|
33
|
+
if ( runCount >= MAINPAGE_REQUESTS_MAX_RUNS ) {
|
|
34
|
+
log( 'stopping requests to the main page due to reached limit.' );
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
return runThroughMainPageRequests( ++runCount );
|
|
38
|
+
} )
|
|
39
|
+
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -61,9 +61,7 @@ function runThroughMainPageRequests( runCount = 1 ) {
|
|
|
61
61
|
class RunJobs {
|
|
62
62
|
|
|
63
63
|
static run() {
|
|
64
|
-
browser.call( () =>
|
|
65
|
-
return runThroughMainPageRequests();
|
|
66
|
-
} );
|
|
64
|
+
browser.call( () => runThroughMainPageRequests() );
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
|
package/Util.js
CHANGED
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
|
+
/**
|
|
5
|
+
* Generate a random number string with some additional extended ASCII.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} prefix A prefix to apply to the generated output.
|
|
8
|
+
* @return {string}
|
|
9
|
+
*/
|
|
4
10
|
getTestString( prefix = '' ) {
|
|
5
11
|
return prefix + Math.random().toString() + '-Iñtërnâtiônàlizætiøn';
|
|
6
12
|
},
|
|
7
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Check if a page is (or, if it doesn't yet exist, would be by default) a wikitext content
|
|
16
|
+
* object, as opposed to e.g. a JSON blob or a content model provided by an extension. This
|
|
17
|
+
* is useful for when a target of a test requires wikitext behaviour, such as testing for
|
|
18
|
+
* having a talk page, being subject to redirects, being editable, or similar concerns.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} target The name of the page in question.
|
|
21
|
+
* @return {Promise<boolean>} True if the target is not wikitext.
|
|
22
|
+
*/
|
|
23
|
+
async isTargetNotWikitext( target ) {
|
|
24
|
+
// First, make sure that the 'mw' object should exist
|
|
25
|
+
await this.waitForModuleState( 'mediawiki.base' );
|
|
26
|
+
|
|
27
|
+
// Then, ask the API for the basic 'info' data about the given page
|
|
28
|
+
return browser.executeAsync( ( target_, done ) => {
|
|
29
|
+
mw.loader.using( 'mediawiki.api' ).then( () => {
|
|
30
|
+
const api = new mw.Api();
|
|
31
|
+
api.get( {
|
|
32
|
+
action: 'query', prop: 'info', titles: target_,
|
|
33
|
+
format: 'json', formatversion: 2
|
|
34
|
+
} ).then( ( result ) => {
|
|
35
|
+
// Finally, return whether said page is wikitext (or would be, if it doesn't yet exist)
|
|
36
|
+
done( result.query.pages[ 0 ].contentmodel !== 'wikitext' );
|
|
37
|
+
} );
|
|
38
|
+
} );
|
|
39
|
+
}, target );
|
|
40
|
+
},
|
|
41
|
+
|
|
8
42
|
/**
|
|
9
43
|
* Wait for a given module to reach a specific state
|
|
10
44
|
*
|
|
@@ -13,14 +47,14 @@ module.exports = {
|
|
|
13
47
|
* @param {number} timeout The wait time in milliseconds before the wait fails
|
|
14
48
|
*/
|
|
15
49
|
async waitForModuleState( moduleName, moduleStatus = 'ready', timeout = 5000 ) {
|
|
16
|
-
await browser.waitUntil(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
50
|
+
await browser.waitUntil(
|
|
51
|
+
() => browser.execute(
|
|
52
|
+
( arg ) => typeof mw !== 'undefined' && mw.loader.getState( arg.name ) === arg.status,
|
|
53
|
+
{ status: moduleStatus, name: moduleName }
|
|
54
|
+
), {
|
|
55
|
+
timeout: timeout,
|
|
56
|
+
timeoutMsg: 'Failed to wait for ' + moduleName + ' to be ' + moduleStatus + ' after ' + timeout + ' ms.'
|
|
57
|
+
}
|
|
58
|
+
);
|
|
25
59
|
}
|
|
26
60
|
};
|
package/index.js
CHANGED
|
@@ -23,11 +23,10 @@ function testTitle( title ) {
|
|
|
23
23
|
* @since 1.1.0
|
|
24
24
|
* @param {string} title Test title
|
|
25
25
|
* @param {string} extension png for screenshots, mp4 for videos
|
|
26
|
-
* @param {string} screenshotPath Optional path
|
|
27
26
|
* @return {string} Full path of screenshot/video file
|
|
28
27
|
*/
|
|
29
|
-
function filePath( title, extension
|
|
30
|
-
return `${
|
|
28
|
+
function filePath( title, extension ) {
|
|
29
|
+
return `${ browser.config.screenshotPath }/${ testTitle( title ) }-${ makeFilenameDate() }.${ extension }`;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
/**
|
|
@@ -35,19 +34,18 @@ function filePath( title, extension, screenshotPath = undefined ) {
|
|
|
35
34
|
*
|
|
36
35
|
* @since 1.0.0
|
|
37
36
|
* @param {string} title Description (will be sanitised and used as file name)
|
|
38
|
-
* @param {string} screenshotPath Optional path
|
|
39
37
|
* @return {string} File path
|
|
40
38
|
*/
|
|
41
|
-
async function saveScreenshot( title
|
|
39
|
+
async function saveScreenshot( title ) {
|
|
42
40
|
// Create sensible file name for current test title
|
|
43
|
-
const path = filePath( title, 'png'
|
|
41
|
+
const path = filePath( title, 'png' );
|
|
44
42
|
// Ensure directory exists, based on WebDriverIO#saveScreenshotSync()
|
|
45
43
|
try {
|
|
46
44
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
47
|
-
fs.statSync(
|
|
45
|
+
fs.statSync( browser.config.screenshotPath );
|
|
48
46
|
} catch ( err ) {
|
|
49
47
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
50
|
-
fs.mkdirSync(
|
|
48
|
+
fs.mkdirSync( browser.config.screenshotPath );
|
|
51
49
|
}
|
|
52
50
|
// Create and save screenshot
|
|
53
51
|
await browser.saveScreenshot( path );
|
|
@@ -75,7 +73,7 @@ function startVideo( ffmpeg, title ) {
|
|
|
75
73
|
] );
|
|
76
74
|
const logBuffer = function ( buffer, prefix ) {
|
|
77
75
|
const lines = buffer.toString().trim().split( '\n' );
|
|
78
|
-
lines.forEach(
|
|
76
|
+
lines.forEach( ( line ) => {
|
|
79
77
|
console.log( prefix + line );
|
|
80
78
|
} );
|
|
81
79
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wdio-mediawiki",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "WebdriverIO plugin for testing a MediaWiki site.",
|
|
5
|
-
"homepage": "https://gerrit.wikimedia.org/g/mediawiki/core/+/master/tests/selenium/wdio-mediawiki
|
|
5
|
+
"homepage": "https://gerrit.wikimedia.org/g/mediawiki/core/+/master/tests/selenium/wdio-mediawiki",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"mediawiki",
|
|
@@ -12,9 +12,6 @@
|
|
|
12
12
|
"*.js",
|
|
13
13
|
"specs/"
|
|
14
14
|
],
|
|
15
|
-
"engines": {
|
|
16
|
-
"node": ">=10.0"
|
|
17
|
-
},
|
|
18
15
|
"dependencies": {
|
|
19
16
|
"mwbot": "2.1.3"
|
|
20
17
|
}
|
package/specs/BlankPage.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const assert = require( 'assert' );
|
|
4
3
|
const BlankPage = require( './../BlankPage' );
|
|
5
4
|
|
|
6
|
-
describe( 'BlankPage',
|
|
7
|
-
it( 'should have its title @daily', async
|
|
5
|
+
describe( 'BlankPage', () => {
|
|
6
|
+
it( 'should have its title @daily', async () => {
|
|
8
7
|
await BlankPage.open();
|
|
9
8
|
|
|
10
9
|
// check
|
|
11
|
-
|
|
10
|
+
await expect( await BlankPage.heading ).toHaveText( 'Blank page' );
|
|
12
11
|
} );
|
|
13
12
|
} );
|
package/wdio-defaults.conf.js
CHANGED
|
@@ -15,6 +15,8 @@ const fs = require( 'fs' );
|
|
|
15
15
|
const path = require( 'path' );
|
|
16
16
|
const logPath = process.env.LOG_DIR || path.join( process.cwd(), 'tests/selenium/log' );
|
|
17
17
|
const { makeFilenameDate, saveScreenshot, startVideo, stopVideo } = require( 'wdio-mediawiki' );
|
|
18
|
+
// T355556: remove when T324766 is resolved
|
|
19
|
+
const dns = require( 'dns' );
|
|
18
20
|
|
|
19
21
|
if ( !process.env.MW_SERVER || !process.env.MW_SCRIPT_PATH ) {
|
|
20
22
|
throw new Error( 'MW_SERVER or MW_SCRIPT_PATH not defined.\nSee https://www.mediawiki.org/wiki/Selenium/How-to/Set_environment_variables\n' );
|
|
@@ -22,8 +24,8 @@ if ( !process.env.MW_SERVER || !process.env.MW_SCRIPT_PATH ) {
|
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* For more details documentation and available options:
|
|
25
|
-
* - https://webdriver.io/docs/configurationfile
|
|
26
|
-
* - https://webdriver.io/docs/
|
|
27
|
+
* - https://webdriver.io/docs/configurationfile
|
|
28
|
+
* - https://webdriver.io/docs/configuration
|
|
27
29
|
*/
|
|
28
30
|
exports.config = {
|
|
29
31
|
// ======
|
|
@@ -54,7 +56,7 @@ exports.config = {
|
|
|
54
56
|
|
|
55
57
|
maxInstances: 1,
|
|
56
58
|
capabilities: [ {
|
|
57
|
-
// For Chrome/Chromium https://
|
|
59
|
+
// For Chrome/Chromium https://www.w3.org/TR/webdriver
|
|
58
60
|
browserName: 'chrome',
|
|
59
61
|
'goog:chromeOptions': {
|
|
60
62
|
// If DISPLAY is set, assume developer asked non-headless or CI with Xvfb.
|
|
@@ -64,7 +66,10 @@ exports.config = {
|
|
|
64
66
|
'--enable-automation',
|
|
65
67
|
...( process.env.DISPLAY ? [] : [ '--headless' ] ),
|
|
66
68
|
// Chrome sandbox does not work in Docker
|
|
67
|
-
...( fs.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] )
|
|
69
|
+
...( fs.existsSync( '/.dockerenv' ) ? [ '--no-sandbox' ] : [] ),
|
|
70
|
+
// Workaround inputs not working consistently post-navigation on Chrome 90
|
|
71
|
+
// https://issuetracker.google.com/issues/42322798
|
|
72
|
+
'--allow-pre-commit-input'
|
|
68
73
|
]
|
|
69
74
|
}
|
|
70
75
|
} ],
|
|
@@ -83,9 +88,9 @@ exports.config = {
|
|
|
83
88
|
bail: 0,
|
|
84
89
|
// Base for browser.url() and wdio-mediawiki/Page#openTitle()
|
|
85
90
|
baseUrl: process.env.MW_SERVER + process.env.MW_SCRIPT_PATH,
|
|
86
|
-
// See also: https://webdriver.io/docs/frameworks
|
|
91
|
+
// See also: https://webdriver.io/docs/frameworks
|
|
87
92
|
framework: 'mocha',
|
|
88
|
-
// See also: https://mochajs.org
|
|
93
|
+
// See also: https://mochajs.org
|
|
89
94
|
// The number of times to retry the entire specfile when it fails as a whole
|
|
90
95
|
specFileRetries: 1,
|
|
91
96
|
// Delay in seconds between the spec file retry attempts
|
|
@@ -97,15 +102,16 @@ exports.config = {
|
|
|
97
102
|
ui: 'bdd',
|
|
98
103
|
timeout: process.env.DEBUG ? ( 60 * 60 * 1000 ) : ( 60 * 1000 )
|
|
99
104
|
},
|
|
100
|
-
// See also: https://webdriver.io/docs/dot-reporter
|
|
105
|
+
// See also: https://webdriver.io/docs/dot-reporter
|
|
101
106
|
reporters: [
|
|
102
|
-
// See also: https://webdriver.io/docs/spec-reporter
|
|
107
|
+
// See also: https://webdriver.io/docs/spec-reporter
|
|
103
108
|
'spec',
|
|
104
|
-
// See also: https://webdriver.io/docs/junit-reporter
|
|
109
|
+
// See also: https://webdriver.io/docs/junit-reporter
|
|
105
110
|
[ 'junit', {
|
|
106
111
|
outputDir: logPath,
|
|
107
112
|
outputFileFormat: function () {
|
|
108
|
-
|
|
113
|
+
const random = Math.random().toString( 16 ).slice( 2, 10 );
|
|
114
|
+
return `WDIO.xunit-${ makeFilenameDate() }-${ random }.xml`;
|
|
109
115
|
}
|
|
110
116
|
} ]
|
|
111
117
|
],
|
|
@@ -114,13 +120,27 @@ exports.config = {
|
|
|
114
120
|
// Hooks
|
|
115
121
|
// =====
|
|
116
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Gets executed just before initializing the webdriver session and test framework.
|
|
125
|
+
* It allows you to manipulate configurations depending on the capability or spec.
|
|
126
|
+
*
|
|
127
|
+
* @param {Object} config wdio configuration object
|
|
128
|
+
* @param {Array.<Object>} capabilities list of capabilities details
|
|
129
|
+
* @param {Array.<string>} specs List of spec file paths that are to be run
|
|
130
|
+
*/
|
|
131
|
+
// T355556: remove when T324766 is resolved
|
|
132
|
+
beforeSession: function () {
|
|
133
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
134
|
+
dns.setDefaultResultOrder( 'ipv4first' );
|
|
135
|
+
},
|
|
136
|
+
|
|
117
137
|
/**
|
|
118
138
|
* Executed before a Mocha test starts.
|
|
119
139
|
*
|
|
120
140
|
* @param {Object} test Mocha Test object
|
|
121
141
|
*/
|
|
122
142
|
beforeTest: function ( test ) {
|
|
123
|
-
ffmpeg = startVideo( ffmpeg, `${test.parent}-${test.title}` );
|
|
143
|
+
ffmpeg = startVideo( ffmpeg, `${ test.parent }-${ test.title }` );
|
|
124
144
|
},
|
|
125
145
|
|
|
126
146
|
/**
|
|
@@ -129,7 +149,7 @@ exports.config = {
|
|
|
129
149
|
* @param {Object} test Mocha Test object
|
|
130
150
|
*/
|
|
131
151
|
afterTest: async function ( test ) {
|
|
132
|
-
await saveScreenshot( `${test.parent}-${test.title}` );
|
|
152
|
+
await saveScreenshot( `${ test.parent }-${ test.title }` );
|
|
133
153
|
stopVideo( ffmpeg );
|
|
134
154
|
}
|
|
135
155
|
};
|