aboutsummaryrefslogtreecommitdiffstats
path: root/test/runner/browserstack/browsers.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/runner/browserstack/browsers.js')
-rw-r--r--test/runner/browserstack/browsers.js211
1 files changed, 0 insertions, 211 deletions
diff --git a/test/runner/browserstack/browsers.js b/test/runner/browserstack/browsers.js
deleted file mode 100644
index 6489cf965..000000000
--- a/test/runner/browserstack/browsers.js
+++ /dev/null
@@ -1,211 +0,0 @@
-import chalk from "chalk";
-import { getBrowserString } from "../lib/getBrowserString.js";
-import { createWorker, deleteWorker, getAvailableSessions } from "./api.js";
-
-const workers = Object.create( null );
-
-/**
- * Keys are browser strings
- * Structure of a worker:
- * {
- * debug: boolean, // Stops the worker from being cleaned up when finished
- * id: string,
- * lastTouch: number, // The last time a request was received
- * url: string,
- * browser: object, // The browser object
- * options: object // The options to create the worker
- * }
- */
-
-// Acknowledge the worker within the time limit.
-// BrowserStack can take much longer spinning up
-// some browsers, such as iOS 15 Safari.
-const ACKNOWLEDGE_INTERVAL = 1000;
-const ACKNOWLEDGE_TIMEOUT = 60 * 1000 * 5;
-
-const MAX_WORKER_RESTARTS = 5;
-
-// No report after the time limit
-// should refresh the worker
-const RUN_WORKER_TIMEOUT = 60 * 1000 * 2;
-
-const WORKER_WAIT_TIME = 30000;
-
-export function touchBrowser( browser ) {
- const fullBrowser = getBrowserString( browser );
- const worker = workers[ fullBrowser ];
- if ( worker ) {
- worker.lastTouch = Date.now();
- }
-}
-
-async function waitForAck( worker, { fullBrowser, verbose } ) {
- delete worker.lastTouch;
- return new Promise( ( resolve, reject ) => {
- const interval = setInterval( () => {
- if ( worker.lastTouch ) {
- if ( verbose ) {
- console.log( `\n${ fullBrowser } acknowledged.` );
- }
- clearTimeout( timeout );
- clearInterval( interval );
- resolve();
- }
- }, ACKNOWLEDGE_INTERVAL );
-
- const timeout = setTimeout( () => {
- clearInterval( interval );
- reject(
- new Error(
- `${ fullBrowser } not acknowledged after ${
- ACKNOWLEDGE_TIMEOUT / 1000 / 60
- }min.`
- )
- );
- }, ACKNOWLEDGE_TIMEOUT );
- } );
-}
-
-async function restartWorker( worker ) {
- await cleanupWorker( worker, worker.options );
- await createBrowserWorker(
- worker.url,
- worker.browser,
- worker.options,
- worker.restarts + 1
- );
-}
-
-export async function restartBrowser( browser ) {
- const fullBrowser = getBrowserString( browser );
- const worker = workers[ fullBrowser ];
- if ( worker ) {
- await restartWorker( worker );
- }
-}
-
-async function ensureAcknowledged( worker ) {
- const fullBrowser = getBrowserString( worker.browser );
- const verbose = worker.options.verbose;
- try {
- await waitForAck( worker, { fullBrowser, verbose } );
- return worker;
- } catch ( error ) {
- console.error( error.message );
- await restartWorker( worker );
- }
-}
-
-export async function createBrowserWorker( url, browser, options, restarts = 0 ) {
- if ( restarts > MAX_WORKER_RESTARTS ) {
- throw new Error(
- `Reached the maximum number of restarts for ${ chalk.yellow(
- getBrowserString( browser )
- ) }`
- );
- }
- const verbose = options.verbose;
- while ( ( await getAvailableSessions() ) <= 0 ) {
- if ( verbose ) {
- console.log( "\nWaiting for available sessions..." );
- }
- await new Promise( ( resolve ) => setTimeout( resolve, WORKER_WAIT_TIME ) );
- }
-
- const { debug, runId, tunnelId } = options;
- const fullBrowser = getBrowserString( browser );
-
- const worker = await createWorker( {
- ...browser,
- url: encodeURI( url ),
- project: "jquery",
- build: `Run ${ runId }`,
-
- // This is the maximum timeout allowed
- // by BrowserStack. We do this because
- // we control the timeout in the runner.
- // See https://github.com/browserstack/api/blob/b324a6a5bc1b6052510d74e286b8e1c758c308a7/README.md#timeout300
- timeout: 1800,
-
- // Not documented in the API docs,
- // but required to make local testing work.
- // See https://www.browserstack.com/docs/automate/selenium/manage-multiple-connections#nodejs
- "browserstack.local": true,
- "browserstack.localIdentifier": tunnelId
- } );
-
- browser.debug = !!debug;
- worker.url = url;
- worker.browser = browser;
- worker.restarts = restarts;
- worker.options = options;
- touchBrowser( browser );
- workers[ fullBrowser ] = worker;
-
- // Wait for the worker to show up in the list
- // before returning it.
- return ensureAcknowledged( worker );
-}
-
-export async function setBrowserWorkerUrl( browser, url ) {
- const fullBrowser = getBrowserString( browser );
- const worker = workers[ fullBrowser ];
- if ( worker ) {
- worker.url = url;
- }
-}
-
-/**
- * Checks that all browsers have received
- * a response in the given amount of time.
- * If not, the worker is restarted.
- */
-export async function checkLastTouches() {
- for ( const [ fullBrowser, worker ] of Object.entries( workers ) ) {
- if ( Date.now() - worker.lastTouch > RUN_WORKER_TIMEOUT ) {
- const options = worker.options;
- if ( options.verbose ) {
- console.log(
- `\nNo response from ${ chalk.yellow( fullBrowser ) } in ${
- RUN_WORKER_TIMEOUT / 1000 / 60
- }min.`
- );
- }
- await restartWorker( worker );
- }
- }
-}
-
-export async function cleanupWorker( worker, { verbose } ) {
- for ( const [ fullBrowser, w ] of Object.entries( workers ) ) {
- if ( w === worker ) {
- delete workers[ fullBrowser ];
- await deleteWorker( worker.id );
- if ( verbose ) {
- console.log( `\nStopped ${ fullBrowser }.` );
- }
- return;
- }
- }
-}
-
-export async function cleanupAllBrowsers( { verbose } ) {
- const workersRemaining = Object.values( workers );
- const numRemaining = workersRemaining.length;
- if ( numRemaining ) {
- try {
- await Promise.all(
- workersRemaining.map( ( worker ) => deleteWorker( worker.id ) )
- );
- if ( verbose ) {
- console.log(
- `Stopped ${ numRemaining } browser${ numRemaining > 1 ? "s" : "" }.`
- );
- }
- } catch ( error ) {
-
- // Log the error, but do not consider the test run failed
- console.error( error );
- }
- }
-}