🇺🇦 We stand with the people of Ukraine. We encourage compassion, and hope for peace. 🇺🇦 Please support humanitarian efforts for the Ukraine crisis through the International Committee of the Red Cross! #StandWithUkraine
With the release of WebdriverIO v8 we introduced the ability to connect with the WebDriver Bidi protocol directly. This allowed users to access the new capabilities of the protocol in a rudimental way as its development progresses. Today, with every browser release more capabilities will be enabled, so it is time for WebdriverIO to step up its integration and make these easier accessible to the user.
With the release of WebdriverIO v8.11 we are adding new WebDriver Bidi interfaces and make them type safe 🎉
The interface of the WebDriver Bidi specification is defined through a Concise Data Definition Language (short CDDL). It describes which payloads can be send to the driver and which responses are expected. Over the last month I've been working on a CDDL parser to help the Browser Testing and Tools Working Group at W3C to validate the CDDL defined in the specification as well as help the WebDriver ecosystem to adopt the protocol.
I've created two NPM packages that hopefully can contribute to that:
cddl: a package to read CDDL and parse it into an AST as well as validate the contents
cddl2ts: a package that allows you to transform a CDDL file into a TypeScript interface that you can use for other TypeScript projects
With some recent changes in the WebdriverIO repository we now generate a perfectly typed WebDriver Bidi interface thanks to those packages, e.g.
We also updated the protocol docs to include new Bidi commands that help users to interact with the protocol using Promises. As browser start to support more Bidi features WebdriverIO will start running more automation on the new protocol, ensuring that your tests use the latest and greatest cross browser automation standards. Here are some features that are about to land in upcoming browser versions:
Add Preload-Scripts: this will be an invaluable command to help WebdriverIO mock Web APIs and inject scripts for introspection
Network Interception: this will make WebdriverIOs mock API for network requests compatible cross browser
HTTP Authentication: enables the ability to load a web page that is protected behind user credentials
Note that even WebdriverIO will offer the latest WebDriver Bidi features, this doesn't mean that those are implemented and shipped in the browser. Every browser vendor has different priorities and resources available to get these new features added and while the teams make great progress it will take more time until everything specified in the protocol lands in a stable browser version. You can be ensured though that WebdriverIO will always provide a typed interface for you to use them once ready.
Furthermore I am working on a proposal to extend the WebdriverIO interface and include a page object next to the already known browser, element and mock objects to simplify accessing commands and events connected to a certain browsing context. For information about that soon!
I want to close up thanking the Mozilla and Google browser teams for their excellent collaboration and efforts to ship this new standard that will enable developers around the world ship high quality web applications in the future.
This article is a must-read for those experiencing headaches with mobile automation testing in the context of Continuous Integration and Continuous Deployment (CICD), particularly when it involves native mobile Apps for Android and iOS. It’s quite challenging to find sufficient resources that cover this specific topic.
Within this article, I will guide you through a detailed step-by-step process on how to create a comprehensive end-to-end test pipeline at no cost, utilizing GitHub Actions for both the iOS and Android platforms. We will be using our beloved WebdriverIO framework throughout the tutorial.
Our challenge is to establish a unified pipeline workflow that enables testing of our native mobile application on both the iOS and Android platforms. In a previous article, we thoroughly explored the process of constructing a pipeline for testing an Android app using an emulator with GitHub Actions. To handle the E2E test for the Android component, we will reuse that workflow. However, we still need to address the remaining bigger challenge of creating a separate job for the iPhone/iPad simulator.
During my research, I came across an incredibly useful but often overlooked feature which is, the macOS GitHub runner comes pre-equipped with Xcode, the necessary SDKs for iPhone iOS simulators. This realization sparked an idea in my mind: why not replicate the process we followed for the Android emulator but this time for the iOS simulator? This is particularly exciting because GitHub Actions’ iOS runner supports virtualization, making it a viable option for our purposes.
This feature allows us to build our pipeline without any additional costs (up to a maximum of 2000 minutes).
As previously mentioned, the GH Actions runner comes packed with a range of available simulators. While we could utilize one of these existing simulators, it would require using the deviceName and it's
randomly changing UUID for each execution. However, you can still extract the relevant UUID using shell commands.
To simplify the process and increase flexibility, we will create our own simulator. Since Xcode is already installed, we can make use of the “xcrun” CLI. To create a simulator from the installed iOS versions using the terminal, simply execute the following command:
Executing this command will result in the immediate creation of a simulator and the subsequent retrieval of its UUID.
To enhance re-usability and optimize the process, we can encapsulate this command within a shell script. With a few modifications, we can ensure that the UUID is stored as an environment variable in GitHub Runner which we will eventually use for our test capabilities.
#!/bin/bash # Set iPhone model and iOS version iphone_model="${IPHONE_MODEL// /-}" ios_version="${IOS_VERSION//./-}" simulator_name="${iphone_model}" simulator_udid=$(xcrun simctl create "$IPHONE_MODEL" "com.apple.CoreSimulator.SimDeviceType.$iphone_model" "com.apple.CoreSimulator.SimRuntime.iOS-$ios_version") # Export the simulator UDID as an environment variable export SIMULATOR_UDID="$simulator_udid" echo "SIMULATOR_UDID=$SIMULATOR_UDID" >> $GITHUB_ENV # Boot the simulator xcrun simctl boot "$simulator_udid"
By using the script above, we can provide the device model and iOS version as environment variables which can be stored in the environment sections in our workflow, this will create the simulator and store its UUID in GITHUB_ENV. This UUID will be essential for configuring the desired capabilities in our tests.
Since we are using IPHONE_MODEL and IOS_VERSION as environment variable in our shell script then we will have to set them in the environment section as shown below.
After successfully creating and booting up the simulator in the previous step, it’s crucial to verify that the process was completed without any issues and that the device is fully prepared for use.
To ensure the successful starting of our test, it is crucial to confirm that the IOS has fully booted. For this purpose, I have created a code snippet that continuously monitors the device’s status until a specific output is obtained, signifying the completion of the simulator’s booting process.
#!/bin/zsh function wait_for_boot() { printf "${G}==> ${BL}Waiting for the simulator to boot...${NC}\n" start_time=$(date +%s) spinner=( "⠹" "⠺" "⠼" "⠶" "⠦" "⠧" "⠇" "⠏" ) i=0 # Get the timeout value from the environment variable or use the default value of 60 seconds timeout=${BOOT_TIMEOUT:-60} while true; do output=$(xcrun simctl bootstatus "$SIMULATOR_UDID") echo "${output}" if [[ $output == *"Device already booted, nothing to do."* ]]; then printf "\e[K${G}==> \u2713 Simulator booted successfully${NC}\n" exit 0 else printf "${YE}==> Please wait ${spinner[$i]} ${NC}\r" i=$(( (i+1) % 8 )) fi elapsed_time=$(( $(date +%s) - $start_time )) if [[ $elapsed_time -ge $timeout ]]; then printf "${RED}==> Timeout waiting for simulator to boot 🕛${NC}\n" exit 1 fi sleep 1 done } # Call the wait_for_boot function wait_for_boot
Proceeding further, we will cover the necessary steps and dependencies required for executing your tests. This includes the installation of Appium, the XCUITest driver, and the essential Node.js libraries.
Since now the key elements required to set up the environment for executing our mobile automation tests on the iOS simulator are ready, Let’s wrap them all into a single yaml file for GH actions
name: Wdio-x-native on: workflow_dispatch: env: IPHONE_MODEL: iPhone 8 IOS_VERSION:16.2 BOOT_TIMEOUT:700 jobs: ios: runs-on: macos-13 steps: -uses: actions/checkout@v3 -name: Export environment variables run:| export IPHONE_MODEL=$IPHONE_MODEL export IOS_VERSION=$IOS_VERSION -name: Start simulator run:| chmod a+x ./sscript/start_simu.sh ./sscript/start_simu.sh -name: Install dependencies run:| npm i -name: Check simulator booting status run:| chmod a+x ./check_simu.sh ./check_simu.sh -name: Execute the test run:| npm run ios