wdio-mediawiki 6.3.2 → 6.4.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 CHANGED
@@ -18,7 +18,8 @@ class Api {
18
18
  baseUrl,
19
19
  username,
20
20
  password,
21
- verbose
21
+ verbose,
22
+ cookies
22
23
  } = options;
23
24
 
24
25
  this.session = {
@@ -27,7 +28,7 @@ class Api {
27
28
  createAccountToken: null
28
29
  };
29
30
 
30
- this.cookies = new Cookies();
31
+ this.cookies = new Cookies( cookies );
31
32
  this.httpClient = new MwApiHttpClient( {
32
33
  cookies: this.cookies,
33
34
  options: {
@@ -62,7 +63,7 @@ class Api {
62
63
  * Do a request with custom parameters to the API. If you
63
64
  * use this function maybe something is missing in core?
64
65
  *
65
- * @param params
66
+ * @param {Object} params
66
67
  * @return {Promise<Object>} The JSON response from the API
67
68
  * @throws {Error} If the request fails
68
69
  */
@@ -211,6 +212,7 @@ class Api {
211
212
  * - options.baseUrl - browser.options.baseUrl
212
213
  * - options.username - browser.options.capabilities['mw:user']
213
214
  * - options.password - browser.options.capabilities['mw:pwd']
215
+ * - options.cookies - extra cookies to send with every API request (name -> value map)
214
216
  * - options.verbose set to true logs every response from MediaWiki
215
217
  *
216
218
  * @param {Object} [options={}] Optional api configuration.
@@ -223,7 +225,8 @@ class Api {
223
225
  * baseUrl: 'https://mw.example.org',
224
226
  * username: 'Admin',
225
227
  * password: process.env.MW_PWD,
226
- * verbose: true
228
+ * verbose: true,
229
+ * cookies: { cookie1: 'value1', cookie2: 'value2' }
227
230
  * });
228
231
  */
229
232
  export const createApiClient = async function ( options = {} ) {
@@ -234,6 +237,7 @@ export const createApiClient = async function ( options = {} ) {
234
237
  baseUrl,
235
238
  username,
236
239
  password,
240
+ cookies: options.cookies,
237
241
  verbose: options.verbose ?? false
238
242
  } );
239
243
  await api.loginGetEditToken( username, password );
@@ -111,7 +111,9 @@ class PrometheusFileReporter extends WDIOReporter {
111
111
  const testDurationInSeconds = ( test.end - test.start ) / 1000;
112
112
  const myTest = this.testMetrics[ test.uid ];
113
113
  myTest.passed++;
114
- myTest.testDurationSecondsMax = Math.max( myTest.testDurationSecondsMax, testDurationInSeconds );
114
+ myTest.testDurationSecondsMax = Math.max(
115
+ myTest.testDurationSecondsMax, testDurationInSeconds
116
+ );
115
117
  myTest.testDurationSecondsSum += testDurationInSeconds;
116
118
  myTest.testDurationSecondsCount += 1;
117
119
  this.spec.passed++;
@@ -121,7 +123,9 @@ class PrometheusFileReporter extends WDIOReporter {
121
123
  const testDurationInSeconds = ( test.end - test.start ) / 1000;
122
124
  const myTest = this.testMetrics[ test.uid ];
123
125
  myTest.failed++;
124
- myTest.testDurationSecondsMax = Math.max( myTest.testDurationSecondsMax, testDurationInSeconds );
126
+ myTest.testDurationSecondsMax = Math.max(
127
+ myTest.testDurationSecondsMax, testDurationInSeconds
128
+ );
125
129
  myTest.testDurationSecondsSum += testDurationInSeconds;
126
130
  myTest.testDurationSecondsCount += 1;
127
131
  this.spec.failed++;
@@ -164,6 +168,7 @@ class PrometheusFileReporter extends WDIOReporter {
164
168
  specMetrics.labels = labels;
165
169
  specMetrics.tests = Object.values( this.testMetrics );
166
170
  const outputPath = path.join( this.outputDir, 'specs-' + workerId + '.json' );
171
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
167
172
  writeFileSync( outputPath, JSON.stringify( specMetrics ), { encoding: 'utf-8' } );
168
173
  }
169
174
  }
@@ -181,11 +186,13 @@ function writeAllProjectMetrics( metricsDir, fileName ) {
181
186
  };
182
187
  const tests = [];
183
188
 
189
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
184
190
  for ( const file of readdirSync( metricsDir ) ) {
185
191
  if ( !file.startsWith( 'specs-' ) || !file.endsWith( '.json' ) ) {
186
192
  continue;
187
193
  }
188
194
  const filePath = path.join( metricsDir, file );
195
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
189
196
  const data = JSON.parse( readFileSync( filePath, 'utf-8' ) );
190
197
 
191
198
  // We have read the raw data, renmove it since we only need the .prom
@@ -298,6 +305,7 @@ function writeAllProjectMetrics( metricsDir, fileName ) {
298
305
  // Only write the file if we have any tests https://phabricator.wikimedia.org/T407831
299
306
  if ( projectMetrics.totalTests > 0 ) {
300
307
  const projectName = projectMetrics.labels.project;
308
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
301
309
  writeFileSync( path.join( metricsDir, `${ projectName }-${ fileName }.prom` ), `${ lines.join( '\n' ) }\n`, 'utf-8' );
302
310
  }
303
311
  }
package/Util.js CHANGED
@@ -42,7 +42,7 @@ export async function isTargetNotWikitext( target ) {
42
42
  action: 'query', prop: 'info', titles: target_,
43
43
  format: 'json', formatversion: 2
44
44
  } ).then( ( result ) => {
45
- // Finally, return whether said page is wikitext (or would be, if it doesn't yet exist)
45
+ // Finally, check if the page is wikitext (or would be, if it doesn't yet exist)
46
46
  done( result.query.pages[ 0 ].contentmodel !== 'wikitext' );
47
47
  } );
48
48
  } );
package/api/Cookies.js CHANGED
@@ -3,14 +3,14 @@
3
3
  */
4
4
  export class Cookies {
5
5
 
6
- constructor() {
7
- this.pairs = {};
6
+ constructor( defaultCookies = {} ) {
7
+ this.pairs = { ...defaultCookies };
8
8
  }
9
9
 
10
10
  /**
11
11
  * Add cookies from Set-Cookie header lines.
12
12
  *
13
- * @param {Iterable<string>} setCookies - Iterable of `Set-Cookie` header lines.
13
+ * @param {string[]} setCookies `Set-Cookie` header lines.
14
14
  */
15
15
  getCookiesFromHeaders( setCookies ) {
16
16
  for ( const line of setCookies ) {
package/index.js CHANGED
@@ -1,10 +1,23 @@
1
1
  import { mkdir } from 'fs/promises';
2
+ import { readFileSync } from 'fs';
2
3
  import os from 'node:os';
3
4
  import process from 'node:process';
5
+ import { resolve } from 'path';
4
6
  import { spawn } from 'child_process';
5
7
 
6
8
  const DISPLAY_BASE = 100;
7
9
 
10
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
11
+ export const version = JSON.parse( readFileSync( new URL( './package.json', import.meta.url ), 'utf8' ) ).version;
12
+
13
+ function getPackageVersion( packageName ) {
14
+ try {
15
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
16
+ return JSON.parse( readFileSync( resolve( process.cwd(), 'node_modules', packageName, 'package.json' ), 'utf8' ) ).version;
17
+ } catch {}
18
+ return 'unknown';
19
+ }
20
+
8
21
  /**
9
22
  * @since 1.1.0
10
23
  * @return {string} File name friendly version of ISO 8601 date and time
@@ -160,6 +173,8 @@ export function logSystemInformation() {
160
173
  console.log( `[System information] Memory (host): ${ formatMegabytesAndGigabytes( freeBytes ) } free` );
161
174
  console.log( `[System information] RAM used by NodeJS ${ formatMegabytesAndGigabytes( rss ) }` );
162
175
  console.log( `[System information] CPU: ${ cores } cores` );
176
+ console.log( `[Package information] WebdriverIO: ${ getPackageVersion( 'webdriverio' ) }` );
177
+ console.log( `[Package information] wdio-mediawiki: ${ version }` );
163
178
  }
164
179
 
165
180
  /**
@@ -190,8 +205,8 @@ export function setDisplay( instances ) {
190
205
  * NodeJS instances.
191
206
  *
192
207
  * @param {number} instances The number of parallel Xvfb servers to launch.
193
- * @param width The screen width
194
- * @param height The screen height
208
+ * @param {number} width The screen width
209
+ * @param {number} height The screen height
195
210
  * @return {object[]} An array of Xvfb child processes.
196
211
  */
197
212
  export function startXvfb( instances, width, height ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdio-mediawiki",
3
- "version": "6.3.2",
3
+ "version": "6.4.0",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "description": "WebdriverIO plugin for testing a MediaWiki site.",
@@ -51,6 +51,8 @@ export const config = {
51
51
  // ============
52
52
 
53
53
  maxInstances: process.env.CI ? 6 : 1,
54
+ // Make sure wdio do not try to start XVFB (we do that ourselves when needed)
55
+ autoXvfb: false,
54
56
  capabilities: [ {
55
57
  // ======
56
58
  // Custom conf keys for MediaWiki
@@ -110,9 +112,11 @@ export const config = {
110
112
  // By default we do not record videos and you can turn it on in CI
111
113
  // Make sure to add it to true and change useBrowserHeadless to false
112
114
  recordVideo: false,
113
- // If you do not want to use browser headless, you need to export DISPLAY
114
- // and have a display for the tests to work
115
- useBrowserHeadless: Boolean( process.env.CI ),
115
+ // Always use headless in CI (if you do not override it),
116
+ // DISPLAY= forces headless and DISPLAY=<anything> forces non headless.
117
+ // When DISPLAY is not set locally, defaults to headless.
118
+ useBrowserHeadless: Boolean( process.env.CI ) ||
119
+ !process.env.DISPLAY,
116
120
  // Only take screenshots on test failures. Setting this to false will take screenshots
117
121
  // independently if a test works or fail
118
122
  screenshotsOnFailureOnly: true,
@@ -150,7 +154,7 @@ export const config = {
150
154
  * Gets executed once before all workers get launched.
151
155
  *
152
156
  * @param {Object} wdioConfig wdio configuration object
153
- * @param capabilities
157
+ * @param {Object[]} capabilities
154
158
  */
155
159
  onPrepare: function ( wdioConfig, capabilities ) {
156
160
  console.log( `Run test targeting ${ wdioConfig.baseUrl }` );