Skip to content

Commit

Permalink
feat(testing): Add script to check BrowserStack support for current c…
Browse files Browse the repository at this point in the history
…onfig (#2437)

* add check-browsers script

* move script and add yarn command

* incorporate PR feedback
  • Loading branch information
lobsterkatie authored Feb 19, 2020
1 parent 644b36c commit 24b3125
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 6 deletions.
3 changes: 3 additions & 0 deletions packages/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"devDependencies": {
"@types/md5": "2.1.33",
"btoa": "^1.2.1",
"chai": "^4.1.2",
"chokidar": "^3.0.2",
"jest": "^24.7.1",
Expand All @@ -36,6 +37,7 @@
"karma-sinon": "^1.0.5",
"karma-typescript": "^4.0.0",
"karma-typescript-es6-transform": "^4.0.0",
"node-fetch": "^2.6.0",
"npm-run-all": "^4.1.2",
"prettier": "^1.17.0",
"prettier-check": "^2.0.0",
Expand Down Expand Up @@ -74,6 +76,7 @@
"test:unit:watch": "karma start test/unit/karma.conf.js --auto-watch --no-single-run",
"test:integration": "test/integration/run.js",
"test:integration:watch": "test/integration/run.js --watch",
"test:integration:checkbrowsers": "node scripts/checkbrowsers.js",
"test:manual": "node test/manual/npm-build.js && rm test/manual/tmp.js",
"size:check": "run-p size:check:es5 size:check:es6",
"size:check:es5": "cat build/bundle.min.js | gzip -9 | wc -c | awk '{$1=$1/1024; print \"ES5: \",$1,\"kB\";}'",
Expand Down
132 changes: 132 additions & 0 deletions packages/browser/scripts/checkbrowsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Script which checks all browsers in test/integration/browser.js against supported BrowserStack browsers
// Meant to be run manually, by running `yarn test:integration:checkbrowsers` from the command line

const btoa = require('btoa');
const fetch = require('node-fetch');
const localConfigs = require('../test/integration/browsers.js');

const browserstackUsername = process.env.BROWSERSTACK_USERNAME;
const browserstackAccessKey = process.env.BROWSERSTACK_ACCESS_KEY;

const hasCreds = () => {
return browserstackUsername !== undefined && browserstackAccessKey !== undefined;
};

const fetchCurrentData = (username, key) => {
const authKey = btoa(`${username}:${key}`);

return fetch('https://api.browserstack.com/5/browsers?flat=true', {
headers: {
Authorization: `Basic ${authKey}`,
},
}).then(response => {
if (response.status >= 200 && response.status < 300) {
return response.json();
} else {
throw new Error(`Unable to fetch data. Status: ${response.status} ${response.statusText}`);
}
});
};

const isMatchingEntry = (key, localConfig, bsConfig) => {
let localValue = localConfig[key];
let bsValue = bsConfig[key];

// all values are either null, undefined, or strings, so checking truthiness should
// save us from trying to lowercase anything that can't handle it
if (localValue) {
localValue = localValue.toLowerCase();
}
if (bsValue) {
bsValue = bsValue.toLowerCase();
}

if (localValue === bsValue) {
return true;
}
if (key === 'browser_version' && localValue === 'latest') {
return true;
}

return false;
};

const isMatchingConfig = (localConfig, bsConfig) => {
const checkKeys = ['os', 'os_version', 'browser', 'device', 'browser_version'];

// bail on the first non-matching entry
if (checkKeys.some(key => !isMatchingEntry(key, localConfig, bsConfig))) {
return false;
}

// while we're here, if we've found a match on everything else, make sure
// real_mobile is up to date. Now the data *really* matches!
if (localConfig.real_mobile !== bsConfig.real_mobile) {
localConfig.real_mobile_updated = true; // flag for later
localConfig.real_mobile = bsConfig.real_mobile;
}

return true;
};

const isSupported = (localConfig, supportedConfigs) => {
return supportedConfigs.some(supportedConfig => isMatchingConfig(localConfig, supportedConfig));
};

const checkLocalConfigsVsBrowserStack = (localConfigs, bsConfigs) => {
const unsupportedConfigs = [];
const realMobileUpdates = [];

// check each local config against the entire collection of BS configs
for (const configName in localConfigs) {
const localConfig = localConfigs[configName];

console.log(`\nChecking ${configName}`);

if (!isSupported(localConfig, bsConfigs)) {
console.log(' UNSUPPORTED');
unsupportedConfigs.push(configName);
} else if (localConfig.real_mobile_updated) {
console.log(' Supported (but needs real_mobile update)');
realMobileUpdates.push(configName);
} else {
console.log(' Supported!');
}
}

// report on unsupported configs
if (unsupportedConfigs.length) {
console.log('\nFound unsupported browser configurations:');
for (const configName of unsupportedConfigs) {
console.log(`\n${configName}: `, localConfigs[configName]);
}
console.log(
'\nPlease visit https://api.browserstack.com/5/browsers or https://api.browserstack.com/5/browsers?flat=true to choose new configurations.',
);
} else {
console.log('\nAll configurations supported!\n');
}

// report on real_mobile updates
if (realMobileUpdates.length) {
console.log('\nFound supported browser configurations which need real_mobile updated:\n');
for (const configName of realMobileUpdates) {
console.log(configName, 'new real_mobile value: ', localConfigs[configName].real_mobile);
}
}
};

const findUnsupportedConfigs = localConfigs => {
if (!hasCreds()) {
console.warn(
'Unable to find API credentials in env. Please export them as BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY.',
);
return;
}

fetchCurrentData(browserstackUsername, browserstackAccessKey)
.then(data => checkLocalConfigsVsBrowserStack(localConfigs, data))
.catch(err => console.log(err));
};

findUnsupportedConfigs(localConfigs);
35 changes: 29 additions & 6 deletions packages/browser/test/integration/browsers.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,60 @@
// To check if all of these browsers are still viable, run
// yarn test:integration:checkbrowsers

module.exports = {
bs_android_4: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Google Nexus 5",
os: "android",
os_version: "4.4",
real_mobile: true,
browser_version: null,
},
bs_android_5: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Google Nexus 9",
os: "android",
os_version: "5.1",
real_mobile: true,
browser_version: null,
},
bs_android_6: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Samsung Galaxy S7",
os: "android",
os_version: "6.0",
real_mobile: true,
browser_version: null,
},
bs_android_7: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Samsung Galaxy S8",
os: "android",
os_version: "7.0",
real_mobile: true,
browser_version: null,
},
bs_android_8: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Samsung Galaxy S9",
os: "android",
os_version: "8.0",
real_mobile: true,
browser_version: null,
},
bs_android_9: {
base: "BrowserStack",
browser: "Android",
browser: "Android Browser",
device: "Samsung Galaxy S9 Plus",
os: "android",
os_version: "9.0",
real_mobile: true,
browser_version: null,
},
bs_ios_11: {
base: "BrowserStack",
Expand All @@ -54,6 +63,7 @@ module.exports = {
os: "ios",
os_version: "11.4",
real_mobile: true,
browser_version: null,
},
bs_ios_12: {
base: "BrowserStack",
Expand All @@ -62,47 +72,60 @@ module.exports = {
os: "ios",
os_version: "12.1",
real_mobile: true,
browser_version: null,
},
bs_ie10: {
base: "BrowserStack",
browser: "IE",
browser_version: "10.0",
os: "Windows",
os_version: "8",
device: null,
real_mobile: null,
},
bs_ie11: {
base: "BrowserStack",
browser: "IE",
browser_version: "11.0",
os: "Windows",
os_version: "10",
device: null,
real_mobile: null,
},
bs_safari: {
base: "BrowserStack",
browser: "Safari",
browser_version: "latest",
os: "OS X",
os_version: "Mojave",
device: null,
real_mobile: null,
},
bs_edge: {
base: "BrowserStack",
browser: "Edge",
browser_version: "latest",
os: "Windows",
os_version: "10",
device: null,
real_mobile: null,
},
bs_firefox: {
base: "BrowserStack",
browser: "Firefox",
browser_version: "latest",
os: "Windows",
os_version: "10",
device: null,
real_mobile: null,
},
bs_chrome: {
base: "BrowserStack",
browser: "Chrome",
browser_version: "latest",
os: "Windows",
os_version: "10",
device: null,
real_mobile: null,
},
};
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2842,6 +2842,11 @@ btoa-lite@^1.0.0:
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=

btoa@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==

buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
Expand Down Expand Up @@ -7896,6 +7901,11 @@ node-fetch@^2.2.0, node-fetch@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"

node-fetch@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==

node-forge@^0.7.4:
version "0.7.6"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
Expand Down

0 comments on commit 24b3125

Please sign in to comment.