Re-add chromedriver retrying from previous webdriver setup (#6846)

* Re-add previous webdriver setup with falling
back to BrowserStack setup

* Add missing webdriver imports
This commit is contained in:
JJ Kasper 2019-04-01 09:09:09 -05:00 committed by Tim Neutkens
parent 8cd7bd1b94
commit 14eef58702
26 changed files with 136 additions and 46 deletions

View file

@ -1,6 +1,7 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import { join } from 'path'
import webdriver from 'next-webdriver'
import { readFileSync, writeFileSync } from 'fs'
import {
nextServer,

View file

@ -1,6 +1,7 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import { readFileSync, writeFileSync } from 'fs'
import webdriver from 'next-webdriver'
import { join } from 'path'
import {
renderViaHTTP,

View file

@ -1,6 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'
import { check } from 'next-test-utils'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
export default (context, render) => {
describe('With CSP enabled', () => {

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import cheerio from 'cheerio'
import { waitFor, check } from 'next-test-utils'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { join } from 'path'
import { check, File, waitFor, getReactErrorOverlayContent, getBrowserBodyText } from 'next-test-utils'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { readFileSync, writeFileSync, renameSync, existsSync } from 'fs'
import { join } from 'path'
import { waitFor, check, getBrowserBodyText } from 'next-test-utils'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
export default (context) => {
describe('process.env', () => {

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
export default (context) => {
describe('Client Navigation 404', () => {

View file

@ -1,6 +1,7 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import { join } from 'path'
import webdriver from 'next-webdriver'
import renderingSuite from './rendering'
import {
waitFor,

View file

@ -1,6 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { waitFor } from 'next-test-utils' /* check, File */
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import webdriver from 'next-webdriver'
import { join } from 'path'
import getPort from 'get-port'
import clone from 'clone'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { check, getBrowserBodyText } from 'next-test-utils'
export default function (context) {

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { renderViaHTTP, getBrowserBodyText, check } from 'next-test-utils'
import cheerio from 'cheerio'

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import webdriver from 'next-webdriver'
import { join, resolve } from 'path'
import { existsSync } from 'fs'
import AbortController from 'abort-controller'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'
import { waitFor } from 'next-test-utils'

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import webdriver from 'next-webdriver'
import { join } from 'path'
import {
nextServer,

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import cheerio from 'cheerio'
import { waitFor, check } from 'next-test-utils'

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, webdriver, browserName */
/* global jasmine, browserName */
import webdriver from 'next-webdriver'
import { readFileSync } from 'fs'
import { join } from 'path'
import {

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { readFile } from 'fs'
import { promisify } from 'util'
import { join } from 'path'

View file

@ -1,5 +1,5 @@
/* eslint-env jest */
/* global webdriver */
import webdriver from 'next-webdriver'
import { readFileSync } from 'fs'
import { join, resolve as resolvePath } from 'path'
import { renderViaHTTP, getBrowserBodyText, waitFor } from 'next-test-utils'

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, test, webdriver */
/* global jasmine, test */
import webdriver from 'next-webdriver'
import { join } from 'path'
import { existsSync } from 'fs'
import {

View file

@ -1,5 +1,6 @@
/* eslint-env jest */
/* global jasmine, webdriver */
/* global jasmine */
import webdriver from 'next-webdriver'
import { join } from 'path'
import {
getReactErrorOverlayContent,

View file

@ -6,7 +6,6 @@ const fetch = require('node-fetch')
const getPort = require('get-port')
const NodeEnvironment = require('jest-environment-node')
const {
HEADLESS,
BROWSER_NAME,
BROWSERSTACK,
BROWSERSTACK_USERNAME,
@ -15,7 +14,6 @@ const {
let browser
let initialWindow
let driverPort = 9515
let browserOptions = {
browserName: BROWSER_NAME || 'chrome'
}
@ -57,8 +55,6 @@ if (isBrowserStack) {
...(isSafari ? safariOpts : {}),
...(isFirefox ? firefoxOpts : {})
}
} else if (HEADLESS !== 'false') {
browserOptions.chromeOptions = { args: ['--headless'] }
}
const newTabPg = `
@ -74,22 +70,20 @@ const newTabPg = `
`
class CustomEnvironment extends NodeEnvironment {
async createBrowser (fromWebdriver = false) {
async createBrowser () {
// always create new browser session if not BrowserStack
if ((!browser && isBrowserStack) || fromWebdriver) {
browser = isBrowserStack
? wd.promiseChainRemote(
'hub-cloud.browserstack.com', // seleniumHost
80, // seleniumPort
BROWSERSTACK_USERNAME,
BROWSERSTACK_ACCESS_KEY
)
: wd.promiseChainRemote(`http://localhost:${driverPort}/`)
if ((!browser && isBrowserStack)) {
browser = wd.promiseChainRemote(
'hub-cloud.browserstack.com', // seleniumHost
80, // seleniumPort
BROWSERSTACK_USERNAME,
BROWSERSTACK_ACCESS_KEY
)
// Setup the browser instance
await browser.init(browserOptions)
if (isBrowserStack) initialWindow = await browser.windowHandle()
global.browser = browser
initialWindow = await browser.windowHandle()
global.bsBrowser = browser
}
if (isBrowserStack) {
@ -128,12 +122,10 @@ class CustomEnvironment extends NodeEnvironment {
}
}
this.global.browserName = BROWSER_NAME
this.global.isBrowserStack = isBrowserStack
// Mock current browser set up
this.global.webdriver = async (appPort, pathname) => {
if (!isBrowserStack) await this.createBrowser(true)
this.global.bsWd = async (appPort, pathname) => {
const url = `http://${deviceIP}:${appPort}${pathname}`
console.log(`\n> Loading browser with ${url}\n`)
if (isBrowserStack) await this.freshWindow()

View file

@ -1,7 +1,7 @@
'use strict'
let globalTeardown
const browser = global.browser
const browser = global.bsBrowser
if (process.env.BROWSERSTACK) {
globalTeardown = () => global.browserStackLocal.killAllProcesses(() => {})

View file

@ -0,0 +1,91 @@
import wd from 'wd'
import getPort from 'get-port'
import waitPort from 'wait-port'
const doHeadless = process.env.HEADLESS !== 'false'
let driverPort = 9515
let webdriver = async function (appPort, pathname) {
if (typeof appPort === 'undefined') {
throw new Error('appPort is undefined')
}
const url = `http://localhost:${appPort}${pathname}`
console.log(`> Start loading browser with url: ${url}`)
// Sometimes browser won't initialize due to some random issues.
// So, we need to timeout the initialization and retry again.
for (let lc = 0; lc < 5; lc++) {
try {
const browser = await getBrowser(url, 5000)
console.log(`> Complete loading browser with url: ${url}`)
return browser
} catch (ex) {
console.warn(`> Error when loading browser with url: ${url}`)
// Try restarting chromedriver max twice
if (lc < 2) {
const chromedriver = require('chromedriver')
console.log('Trying to restart chromedriver with random port')
driverPort = await getPort()
chromedriver.stop()
chromedriver.start([`--port=${driverPort}`])
// https://github.com/giggio/node-chromedriver/issues/117
await waitPort({
port: driverPort,
timeout: 1000 * 30 // 30 seconds
})
continue
}
if (ex.message === 'TIMEOUT') continue
throw ex
}
}
console.error(`> Tried 5 times. Cannot load the browser for url: ${url}`)
throw new Error(`Couldn't start the browser for url: ${url}`)
}
function getBrowser (url, timeout) {
const browser = wd.promiseChainRemote(`http://localhost:${driverPort}/`)
return new Promise((resolve, reject) => {
let timeouted = false
const timeoutHandler = setTimeout(() => {
timeouted = true
const error = new Error('TIMEOUT')
reject(error)
}, timeout)
browser.init({
browserName: 'chrome',
...(doHeadless ? {
chromeOptions: { args: ['--headless'] }
} : {})
}).get(url, err => {
if (timeouted) {
try {
browser.close(() => {
// Ignore errors
})
} catch (err) {
// Ignore
}
return
}
clearTimeout(timeoutHandler)
if (err) {
reject(err)
return
}
resolve(browser)
})
})
}
if (global.isBrowserStack) webdriver = global.bsBrowser
export default webdriver