aboutsummaryrefslogtreecommitdiffstats
path: root/test/runner/selenium/queue.js
blob: 863db4d9b1daa17d88b53f87bba14363a65855b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Build a queue that runs both browsers and modules
// in parallel when the length reaches the concurrency limit
// and refills the queue when one promise resolves.

import chalk from "chalk";
import { getBrowserString } from "../lib/getBrowserString.js";
import { runSelenium } from "./runSelenium.js";
import { runJSDOM } from "../jsdom.js";

const promises = [];
const queue = [];

const SELENIUM_WAIT_TIME = 100;

// Limit concurrency to 8 by default in selenium
// BrowserStack defaults to the max allowed by the plan
// More than this will log MaxListenersExceededWarning
const MAX_CONCURRENCY = 8;

export function addSeleniumRun( url, browser, options ) {
	queue.push( { url, browser, options } );
}

export async function runAllSelenium( { concurrency = MAX_CONCURRENCY, verbose } ) {
	while ( queue.length ) {
		const next = queue.shift();
		const { url, browser, options } = next;

		const fullBrowser = getBrowserString( browser, options.headless );
		console.log(
			`\nRunning ${ chalk.yellow( options.modules.join( ", " ) ) } tests ` +
				`in ${ chalk.yellow( fullBrowser ) } (${ chalk.bold( options.reportId ) })...`
		);

		// Wait enough time between requests
		// to give concurrency a chance to update.
		// In selenium, this helps avoid undici connect timeout errors.
		await new Promise( ( resolve ) => setTimeout( resolve, SELENIUM_WAIT_TIME ) );

		if ( verbose ) {
			console.log( `\nTests remaining: ${ queue.length + 1 }.` );
		}

		let promise;
		if ( browser.browser === "jsdom" ) {
			promise = runJSDOM( url, options );
		} else {
			promise = runSelenium( url, browser, options );
		}

		// Remove the promise from the list when it resolves
		promise.then( () => {
			const index = promises.indexOf( promise );
			if ( index !== -1 ) {
				promises.splice( index, 1 );
			}
		} );

		// Add the promise to the list
		promises.push( promise );

		// Wait until at least one promise resolves
		// if we've reached the concurrency limit
		if ( promises.length >= concurrency ) {
			await Promise.any( promises );
		}
	}

	await Promise.all( promises );
}