-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Karma Launcher: automatic device selection (#75)
- The Karma BrowserStack launcher chooses the device automatically depending on the given iOS/Android version - Improve the logging a bit - Fix an excess underscore in the readme - Bump the minor version because of a breaking change
- Loading branch information
Showing
15 changed files
with
265 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths. | ||
# See https://help.github.com/articles/about-code-owners/ | ||
|
||
* @fpkamp @Finesse | ||
* @Finesse |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import { WebDriver } from 'selenium-webdriver' | ||
|
||
export type BrowserMap = Map<string, { browser: WebDriver; session: string }> | ||
export type BrowserMap = Map<string, { browser: WebDriver; sessionId: string }> | ||
|
||
export function makeBrowserMapFactory(): BrowserMap { | ||
return new Map<string, { browser: WebDriver; session: string }>() satisfies BrowserMap | ||
return new Map<string, { browser: WebDriver; sessionId: string }>() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { Browser } from 'browserstack' | ||
import { Logger } from './karma_logger' | ||
import { BrowserStackCredentials, getBrowsers } from './browserstack_helpers' | ||
|
||
/** | ||
* Loads and caches the list of browsers supported by BrowserStack | ||
*/ | ||
export class BrowserStackBrowsers { | ||
private _allBrowsersPromise?: Promise<Browser[]> | ||
constructor(private _credentials: BrowserStackCredentials) {} | ||
|
||
public async getIOSDevices( | ||
osVersion: string | null, | ||
deviceType: 'iphone' | 'ipad' | null, | ||
browserType: 'safari' | 'chrome' | null, | ||
realDevices: boolean | null, | ||
log: Logger, | ||
): Promise<Browser[]> { | ||
const allBrowsers = await this.getAllBrowsers(log) | ||
return allBrowsers.filter( | ||
(browser) => | ||
browser.os === 'ios' && | ||
ignoreNullExpected(doesOSVersionMatch, browser, osVersion) && | ||
ignoreNullExpected(doesDeviceTypeMatch, browser, deviceType) && | ||
ignoreNullExpected(doesIOSBrowserTypeMatch, browser, browserType) && | ||
ignoreNullExpected(doesRealDeviceMatch, browser, realDevices), | ||
) | ||
} | ||
|
||
public async getAndroidDevices( | ||
osVersion: string | null, | ||
browserType: 'chrome' | 'samsung' | null, | ||
realDevices: boolean | null, | ||
log: Logger, | ||
): Promise<Browser[]> { | ||
const allBrowsers = await this.getAllBrowsers(log) | ||
return allBrowsers.filter( | ||
(browser) => | ||
browser.os === 'android' && | ||
ignoreNullExpected(doesOSVersionMatch, browser, osVersion) && | ||
ignoreNullExpected(doesAndroidBrowserTypeMatch, browser, browserType) && | ||
ignoreNullExpected(doesRealDeviceMatch, browser, realDevices), | ||
) | ||
} | ||
|
||
private async getAllBrowsers(log: Logger) { | ||
this._allBrowsersPromise ??= getBrowsers(this._credentials, log) | ||
return await this._allBrowsersPromise | ||
} | ||
} | ||
|
||
export function makeBrowserStackBrowsers(browserStackCredentials: BrowserStackCredentials): BrowserStackBrowsers { | ||
return new BrowserStackBrowsers(browserStackCredentials) | ||
} | ||
|
||
function doesOSVersionMatch(browser: Browser, expectedOSVersion: string) { | ||
return browser.os_version === expectedOSVersion | ||
} | ||
|
||
function doesDeviceTypeMatch(browser: Browser, expectedDeviceType: string) { | ||
return browser.device?.slice(0, expectedDeviceType.length).toLowerCase() === expectedDeviceType.toLowerCase() | ||
} | ||
|
||
function doesRealDeviceMatch(browser: Browser, expectedRealDevice: boolean) { | ||
return browser.real_mobile === expectedRealDevice | ||
} | ||
|
||
function doesIOSBrowserTypeMatch(browser: Browser, expectedBrowserType: 'safari' | 'chrome') { | ||
if (expectedBrowserType === 'safari') { | ||
return browser.browser === 'iphone' || browser.browser === 'ipad' | ||
} else if (expectedBrowserType === 'chrome') { | ||
// The browser name accepted by BrowserStack is "Chrome" despite returning "chromium" from /automate/browsers.json | ||
return browser.browser === 'chromium' | ||
} else { | ||
return browser.browser === expectedBrowserType | ||
} | ||
} | ||
|
||
function doesAndroidBrowserTypeMatch(browser: Browser, expectedBrowserType: 'chrome' | 'samsung') { | ||
if (expectedBrowserType === 'chrome') { | ||
return browser.browser === 'android' | ||
} else { | ||
return browser.browser === expectedBrowserType | ||
} | ||
} | ||
|
||
function ignoreNullExpected<T>( | ||
criterion: (browser: Browser, expected: T) => boolean, | ||
browser: Browser, | ||
expected: T | null, | ||
): boolean { | ||
if (expected === null) { | ||
return true | ||
} | ||
return criterion(browser, expected) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,4 @@ | ||
export { default as karmaPlugin } from './karma_plugin' | ||
export { sslConfiguration } from './server_certificates' | ||
export * as httpHttpsServer from './http_https_server' | ||
export { setHttpsAndServerForKarma } from './karma_https_config' | ||
export { Arguments as BrowserFlags } from './arguments' | ||
export { BrowserStackSessionFactory, BrowserStackSessionFactoryConfig } from './browserstack_session_factory' | ||
export { BrowserStackCapabilitiesFactory } from './browserstack_capabilities_factory' | ||
export { getBrowserStackCredentials } from './browserstack_helpers' | ||
export { BrowserStackLocalManager } from './browserstack_local_manager' | ||
export { makeKarmaConfigurator } from './karma_configuration' |
Oops, something went wrong.