Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mobile] - E2E Tests Remove SauceLabs in favor of Buildkite #55813

Draft
wants to merge 13 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions packages/react-native-editor/__device-tests__/helpers/caps.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const ios = {
args: [ 'uitesting' ],
},
autoLaunch: false,
usePrebuiltWDA: true,
simulatorStartupTimeout: 240,
reduceMotion: true,
};

exports.iosLocal = ( { iPadDevice = false } ) => ( {
Expand All @@ -24,23 +27,22 @@ exports.iosLocal = ( { iPadDevice = false } ) => ( {
pixelRatio: ! iPadDevice
? iOSConfig.pixelRatio.iPhone
: iOSConfig.pixelRatio.iPad,
usePrebuiltWDA: true,
} );

exports.iosServer = ( { iPadDevice = false } ) => ( {
...ios,
deviceName: ! iPadDevice
? iOSConfig.saucelabs.deviceName
: iOSConfig.saucelabs.deviceTabletName,
platformVersion: iOSConfig.local.platformVersion,
? iOSConfig.local.deviceName
: iOSConfig.local.deviceTabletName,
platformVersion: iOSConfig.buildkite.platformVersion,
pixelRatio: ! iPadDevice
? iOSConfig.pixelRatio.iPhone
: iOSConfig.pixelRatio.iPad,
} );

exports.android = {
platformVersion: androidConfig.local.platformVersion,
deviceName: androidConfig.saucelabs.deviceName,
deviceName: androidConfig.local.deviceName,
automationName: 'UiAutomator2',
appPackage: 'com.gutenberg',
appActivity: 'com.gutenberg.MainActivity',
Expand All @@ -49,11 +51,6 @@ exports.android = {
autoLaunch: false,
};

// SauceLabs config
exports.sauceOptions = {
appiumVersion: '2.0.0',
};

exports.prefixKeysWithAppium = ( obj ) => {
return Object.fromEntries(
Object.entries( obj ).map( ( [ key, value ] ) => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
"deviceTabletName": "iPad (10th generation)",
"platformVersion": "16.2"
},
"saucelabs": {
"deviceName": "iPhone 14 Simulator",
"deviceTabletName": "iPad (10th generation) Simulator"
},
"buildkite": {
"platformVersion": "16.4"
},
Expand All @@ -21,9 +17,6 @@
"local": {
"deviceName": "Pixel_3_XL_API_30",
"platformVersion": "11.0"
},
"saucelabs": {
"deviceName": "Google Pixel 3 XL GoogleAPI Emulator"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,3 @@ exports.local = {
host: '127.0.0.1',
port: 4723, // Port for local Appium runs.
};

exports.sauce = {
user: process.env.SAUCE_USERNAME,
key: process.env.SAUCE_ACCESS_KEY,
hostname: 'ondemand.us-west-1.saucelabs.com',
port: 443,
baseUrl: 'wd/hub',
};
70 changes: 17 additions & 53 deletions packages/react-native-editor/__device-tests__/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const childProcess = require( 'child_process' );
// eslint-disable-next-line import/no-extraneous-dependencies, import/named
import { remote, Key } from 'webdriverio';

const crypto = require( 'crypto' );
const path = require( 'path' );
/**
* Internal dependencies
Expand All @@ -15,7 +14,6 @@ const {
iosServer,
iosLocal,
android,
sauceOptions,
prefixKeysWithAppium,
} = require( './caps' );
const AppiumLocal = require( './appium-local' );
Expand All @@ -26,7 +24,7 @@ const defaultPlatform = 'android';
const rnPlatform = process.env.TEST_RN_PLATFORM || defaultPlatform;
const iPadDevice = process.env.IPAD;

// Environment setup, local environment or Sauce Labs.
// Environment setup, local environment or server.
const defaultEnvironment = 'local';
const testEnvironment = process.env.TEST_ENV || defaultEnvironment;

Expand All @@ -48,7 +46,6 @@ const backspace = '\u0008';

const IOS_BUNDLE_ID = 'org.wordpress.gutenberg.development';
const ANDROID_COMPONENT_NAME = 'com.gutenberg/.MainActivity';
const SAUCE_LABS_TIMEOUT = 240;

const timer = ( ms ) => new Promise( ( res ) => setTimeout( res, ms ) );

Expand Down Expand Up @@ -80,29 +77,22 @@ const PLATFORM_NAME = isAndroid() ? 'Android' : 'iOS';

// Initialises the driver and desired capabilities for appium.
const setupDriver = async () => {
const branch = process.env.CIRCLE_BRANCH || '';
const safeBranchName = branch.replace( /\//g, '-' );
if ( isLocalEnvironment() ) {
try {
appiumProcess = await AppiumLocal.start( {
port: localAppiumPort,
} );
} catch ( err ) {
// Ignore error here, Appium is probably already running (Appium Inspector has its own server for instance)
// eslint-disable-next-line no-console
await console.log(
'Could not start Appium server',
err.toString()
);
}
try {
appiumProcess = await AppiumLocal.start( {
port: localAppiumPort,
} );
} catch ( err ) {
// Ignore error here, Appium is probably already running (Appium Inspector has its own server for instance)
// eslint-disable-next-line no-console
await console.log( 'Could not start Appium server', err.toString() );
}

let desiredCaps;
if ( isAndroid() ) {
desiredCaps = { ...android };
desiredCaps.app = path.resolve( localAndroidAppPath );
if ( isLocalEnvironment() ) {
const androidDeviceID = getAndroidEmulatorID();
desiredCaps.app = path.resolve( localAndroidAppPath );
desiredCaps.udid = androidDeviceID;
try {
const androidVersion = childProcess
Expand All @@ -121,14 +111,9 @@ const setupDriver = async () => {
} catch ( error ) {
// Ignore error.
}
} else {
desiredCaps.app = `storage:filename=Gutenberg-${ safeBranchName }.apk`; // App should be preloaded to sauce storage, this can also be a URL.
desiredCaps.newCommandTimeout = SAUCE_LABS_TIMEOUT;
}
} else {
desiredCaps = iosServer( { iPadDevice } );
desiredCaps.newCommandTimeout = SAUCE_LABS_TIMEOUT;
desiredCaps.app = `storage:filename=Gutenberg-${ safeBranchName }.app.zip`; // App should be preloaded to sauce storage, this can also be a URL.
if ( isLocalEnvironment() ) {
desiredCaps = iosLocal( { iPadDevice } );

Expand All @@ -154,32 +139,17 @@ const setupDriver = async () => {
`Using iOS ${ desiredCaps.platformVersion } platform version`
);
}

desiredCaps.app = path.resolve( localIOSAppPath );
desiredCaps.derivedDataPath = path.resolve( webDriverAgentPath );
}
desiredCaps.app = path.resolve( localIOSAppPath );
desiredCaps.derivedDataPath = path.resolve( webDriverAgentPath );
}

const sauceOptionsConfig = ! isLocalEnvironment()
? {
'sauce:options': {
...sauceOptions,
name: `Gutenberg Editor Tests[${ rnPlatform }]-${ branch }`,
tags: [ 'Gutenberg', branch ],
},
}
: {};
const serverConfig = isLocalEnvironment()
? serverConfigs.local
: serverConfigs.sauce;

const driver = await remote( {
...serverConfig,
...serverConfigs.local,
logLevel: 'error',
capabilities: {
platformName: PLATFORM_NAME,
...prefixKeysWithAppium( desiredCaps ),
...sauceOptionsConfig,
},
} );

Expand All @@ -189,16 +159,10 @@ const setupDriver = async () => {

const stopDriver = async ( driver ) => {
if ( ! isLocalEnvironment() ) {
const sessionId = driver.sessionId;

const secret = `${ serverConfigs.sauce.user }:${ serverConfigs.sauce.key }`;
const token = crypto
.createHmac( 'md5', secret )
.update( sessionId )
.digest( 'hex' );
const jobURL = `https://app.saucelabs.com/tests/${ sessionId }?auth=${ token }`;
// eslint-disable-next-line no-console
console.log( `You can view the video of this test run at ${ jobURL }` );
console.log(
`You can view the video of this test run in the artifacts tab`
);
}
if ( driver === undefined ) {
return;
Expand Down Expand Up @@ -394,7 +358,7 @@ const selectTextFromElement = async ( driver, element ) => {
const selectAllElement = await driver.$(
'//XCUIElementTypeMenuItem[@name="Select All"]'
);
await selectAllElement.waitForDisplayed( { timeout } );
await selectAllElement.waitForDisplayed( { timeout: 3000 } );
await selectAllElement.click();
}
};
Expand Down
3 changes: 2 additions & 1 deletion packages/react-native-editor/bin/build-e2e-wda.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set -o pipefail
# Load configurations from JSON file
CONFIG_FILE="$(pwd)/__device-tests__/helpers/device-config.json"
IOS_DEVICE_NAME=$(jq -r '.ios.local.deviceName' "$CONFIG_FILE")
IOS_PLATFORM_VERSION=$(jq -r '.ios.local.platformVersion' "$CONFIG_FILE")
# Use the value from the environment variable if set, otherwise use the value from the JSON file
IOS_PLATFORM_VERSION="${IOS_PLATFORM_VERSION:-$(jq -r '.ios.local.platformVersion' "$CONFIG_FILE")}"

xcodebuild -project ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "platform=iOS Simulator,name=$IOS_DEVICE_NAME,OS=$IOS_PLATFORM_VERSION" -derivedDataPath ios/build/WDA
Loading