Files
cromite/tools/tests/test_webdriver.js
T
Carmelo Messina 358e4c93ae Add cromite test support: allows the activation of specific APIs used for cromite testing (#1271)
API are only available on the chrome://version page.
It allows the use of tools such as Browserstack for test automation.
Do not activate the corresponding options (available in the developer
settings) if you do not know what you are doing.
2025-08-26 09:05:34 +02:00

338 lines
9.6 KiB
JavaScript

const { remote } = require('webdriverio');
const { bootstrap } = require('global-agent');
const path = require('node:path');
const fs = require('node:fs/promises');
const { appendFile } = require('node:fs');
const { count } = require('node:console');
// export GLOBAL_AGENT_HTTP_PROXY=$HTTPS_PROXY
bootstrap();
let driver;
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
const click = async el => {
try {
const x = await driver.$(el);
await x.click();
return true;
}
catch {
return false;
}
}
const clickByUIautomator = async el => {
const x = await driver.$("-android uiautomator:" + el);
await x.click();
return x;
}
const pressBack = async times => {
for (let t = 0; t < times; t++)
await driver.executeScript("mobile: pressKey", [{ "keycode": 4 }]); // BACK
}
const downFor = async times => {
for (let t = 0; t < times; t++)
await driver.executeScript("mobile: pressKey", [{ "keycode": 20 }]); // DOWN
}
const goto = async (selectorKey, url) => {
let el4 = await clickByUIautomator(
'new UiSelector().resourceId("' + selectorKey + ':id/url_bar")');
await el4.addValue(url);
await clickByUIautomator(
'new UiSelector().resourceId("' + selectorKey + ':id/line_1")');
}
function MakePath(config, file) {
return path.join(
config.outputFolder,
config.deviceName.replaceAll(' ', '_'),
file
)
}
// driver.addCommand('sendCommandFromWebSocket', command('POST', '/session/:sessionId/chromium/send_command', {
// command: 'sendCommandFromWebSocket',
// description: 'sendCommandFromWebSocket chromium command',
// ref: 'https://vendor.com/commands/#myNewCommand',
// // variables: [{
// // name: 'someId',
// // description: 'some id to something'
// // }],
// parameters: [{
// name: 'method',
// type: 'string',
// description: 'a valid parameter',
// required: true
// }, {
// name: 'params',
// type: 'object',
// description: 'a valid parameter',
// required: true
// }, {
// name: 'id',
// type: 'number',
// description: 'a valid parameter',
// required: true
// }]
// }))
// await driver.sendCommandFromWebSocket("lll", {}, -1);
async function testApp(isLocal, config) {
console.log("Starting");
const logDirectory = MakePath(config, "");
try {
await fs.mkdir(logDirectory, { recursive: true });
} catch {
if (!config.skipCheckDirectory) {
console.log("Directory " + logDirectory + " already exists.");
process.exit(0);
}
}
let selectorKey = "org.cromite.cromite";
let isChromium = false;
if (config.appName == "chromium") {
selectorKey = "org.chromium.chrome"; //.stable"; //"org.chromium.chrome";
isChromium = true;
}
const capabilities_local = {
platformName: 'android',
'appium:automationName': 'UiAutomator2',
'appium:appPackage': selectorKey,
'appium:appActivity': 'com.google.android.apps.chrome.Main',
'appium:showChromedriverLog': true,
//'appium:recreateChromeDriverSessions': true,
'appium:chromeOptions': {
'androidDeviceSocket': 'chrome_devtools_remote', // cat /proc/net/unix
'androidExecName': 'unusedbutimportant',
},
};
const capabilities_bs = {
"platformName": "android",
"appium:deviceName": config.deviceName,
"appium:app": config.appName,
'bstack:options': {
"appiumVersion": "2.4.1",
"disableAnimations": "true",
"userName": config.BROWSERSTACK_USERNAME,
"accessKey": config.BROWSERSTACK_ACCESS_KEY,
},
// Set other BrowserStack capabilities
// 'project' : 'First NodeJS project',
// 'build' : 'Node Android',
// 'name': 'first_test',
// 'unicodeKeyboard': 'true',
// 'resetKeyboard': 'true',
};
if (!isLocal) {
driver = await remote({
capabilities: capabilities_bs,
hostname: 'hub-cloud.browserstack.com',
path: '/wd/hub',
protocol: 'https',
port: 443,
strictSSL: true,
logLevel: 'trace',
});
} else {
driver = await remote({
capabilities: capabilities_local,
hostname: '127.0.0.1',
port: 4723,
});
}
try {
const info = await driver.executeScript("mobile: deviceInfo", [{}]);
console.log(info);
await fs.writeFile(MakePath(config, "info.json"), JSON.stringify(info));
// cromite
const terms_accept_present = await driver.findElement("id", selectorKey + ":id/terms_accept");
console.log(!terms_accept_present.error);
if (!terms_accept_present.error) {
await click("id:" + selectorKey + ":id/terms_accept");
await clickByUIautomator(
'new UiSelector().resourceId("' + selectorKey + ':id/default_search_engine_dialog_options")' +
'.childSelector(new UiSelector().className("android.widget.RadioButton"))');
await click("id:" + selectorKey + ":id/button_primary");
}
// chromium
if (isChromium) await sleep(4000);
const signin_fre_dismiss_button = await await driver.findElement("id", selectorKey + ":id/signin_fre_dismiss_button");
if (!signin_fre_dismiss_button.error) {
await click("id:" + selectorKey + ":id/signin_fre_dismiss_button");
}
else {
const signin_fre_continue_button = await await driver.findElement("id", selectorKey + ":id/signin_fre_continue_button");
if (!signin_fre_continue_button.error) {
await click("id:" + selectorKey + ":id/signin_fre_continue_button");
}
}
// click menu
await clickByUIautomator(
'new UiSelector().resourceId("' + selectorKey + ':id/menu_button")');
await sleep(1000);
// click on preferences
if (!await click("id:" + selectorKey + ":id/preferences_id")) {
await driver.executeScript("mobile:flingGesture",
[{ "left": 400, "top": 100, "width": 200, "height": 200, "direction": "down" }]);
await click("id:" + selectorKey + ":id/preferences_id");
}
await sleep(1000);
// disable adblock
await clickByUIautomator(
'new UiSelector().text("Adblock Plus settings")');
await sleep(1000);
await clickByUIautomator(
'new UiSelector().text("Enable Adblock Plus")');
// go back on preferences
await pressBack(1);
await sleep(1000);
// move preferences layout
if (!await driver.executeScript("mobile:flingGesture",
[{ "left": 100, "top": 100, "width": 200, "height": 400, "direction": "down" }])) {
await downFor(20);
}
await sleep(1000);
// click on developer options
await clickByUIautomator(
'new UiSelector().text("Developer options")');
// enable cromite test pref
await clickByUIautomator(
'new UiSelector().text("Enable support for cromite test")');
// enable webview mode (only if chromium or is local)
if (!isLocal && !isChromium) {
await clickByUIautomator(
'new UiSelector().text("Enable webview support for cromite test")');
}
// enable pixel perfect mode
await clickByUIautomator(
'new UiSelector().text("Pixel Perfect Mode")');
// restart cromite
await clickByUIautomator(
'new UiSelector().resourceId("' + selectorKey + ':id/snackbar_button")');
await sleep(2000);
// wait for restart
let count = 0;
while ((await driver.findElement("id", selectorKey + ":id/url_bar")).error) {
await sleep(1000);
count++;
if (count > 10) break;
}
// open chrome://version
await goto(selectorKey, "chrome://version");
// change the context
let contexts = await driver.getContexts();
console.log(contexts);
if (!isLocal && !isChromium) {
await driver.switchContext('WEBVIEW_' + selectorKey);
} else {
await driver.switchContext('WEBVIEW_chrome');
}
contexts = await driver.getContexts();
console.log(contexts);
// start update of cromite fonts pack
await driver.executeScript(
'await window.cromite.startComponentUpdate("gcmjkmgdlgnkkcocmoeiminaijmmjnii")', []);
count = 0;
for (; ;) {
let version = await driver.executeScript(
'return JSON.parse(await window.cromite.getComponentData("gcmjkmgdlgnkkcocmoeiminaijmmjnii")).version;', []);
console.log(version);
if (version != "0.0.0.0") break;
count++;
if (count > 20) break;
await sleep(10000);
}
// open creepjs
await driver.executeScript('window.location.href="https://abrahamjuliot.github.io/creepjs"', []);
if (!isLocal)
await sleep(10000);
else
await sleep(30000);
// get creepjs json
let creep = await driver.executeScript("return JSON.stringify(window.Creep);", []);
await fs.writeFile(MakePath(config, "creep.json"), creep);
let fingerprint = await driver.executeScript("return JSON.stringify(window.Fingerprint);", []);
await fs.writeFile(MakePath(config, "fingerprint.json"), fingerprint);
} finally {
await driver.deleteSession();
driver = undefined;
}
}
if (process.argv.length <= 3) {
console.error('Args:');
console.error(' [local|bs] running environment');
console.error(' [devicename] device');
console.error(' [app name] bs device name');
process.exit(1);
}
if (process.env.BROWSERSTACK_OUTPUT_FOLDER === undefined) {
console.error('set BROWSERSTACK_OUTPUT_FOLDER env variable');
process.exit(1);
}
let isLocal = process.argv[2] === 'local';
if (!isLocal) {
if (process.env.BROWSERSTACK_USERNAME === undefined) {
console.error('set BROWSERSTACK_USERNAME env variable');
process.exit(1);
}
if (process.env.BROWSERSTACK_ACCESS_KEY === undefined) {
console.error('set BROWSERSTACK_ACCESS_KEY env variable');
process.exit(1);
}
testApp(/*isLocal*/ false, {
deviceName: process.argv[3],
appName: process.argv[4],
BROWSERSTACK_USERNAME: process.env.BROWSERSTACK_USERNAME,
BROWSERSTACK_ACCESS_KEY: process.env.BROWSERSTACK_ACCESS_KEY,
outputFolder: process.env.BROWSERSTACK_OUTPUT_FOLDER,
skipCheckDirectory: false,
});
} else {
testApp(/*isLocal*/ true, {
deviceName: process.argv[3],
appName: process.argv[4],
outputFolder: process.env.BROWSERSTACK_OUTPUT_FOLDER,
skipCheckDirectory: true,
});
}