
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
selenium-appium
Advanced tools
A selenium-webdriver extension to support native app testing by Mobile JSON Wire Protocol which appium supports, also provides easy wait for element for pages or navigation among pages, and supports PageObject pattern
selenium-appium is selenium-webdriver extension to make selenium-webdriver to drive Appium to run automation for native, hybrid and mobile web and desktop apps.
http://localhost:4723/wd/hub to http://localhost:4723. The goal is to remove appium from the project and use winappdriver to launch and stop WinAppDrivernpm i selenium-appium --save-dev
test("By2 used in selenium-webdriver.WebDriver", async () => {
const webdriver = await new Builder()
.usingServer(url)
.withCapabilities(capabilities)
.build();
const element = await webdriver.wait(until.elementLocated(By2.nativeName('One')));
await element.click();
await webdriver.quit();
});
test("By2 Supports multiple webdriver2", async () => {
const webdriver = new WebDriver2();
await webdriver.startWithCapabilities(capabilities)
await By2.nativeName('One', webdriver).click();
await webdriver.quit();
});
test("By2 deduced WebDriver2 for single WebDriver2", async () => {
await driver.startWithCapabilities(capabilities)
await By2.nativeName('One').click();
await driver.quit();
});
There are two ways to initialize the driver: startWithWebDriver or startWithWebDriver.
startWithWebDriver allows you to attach the driver to existing WebDriver if capability is not enough for your testing.
test("simple webdriver2, and driver create from WebDriver", async () => {
const webdriver = await new Builder()
.usingServer(url)
.withCapabilities(capabilities)
.build();
await driver.startWithWebDriver(webdriver);
await By2.nativeName('One').click();
await webdriver.quit();
});
test("Multiple webdriver2", async () => {
const webdriver = new WebDriver2();
await webdriver.startWithCapabilities(capabilities)
await By2.nativeName('One', webdriver).click();
await webdriver.quit();
});
test("Simple Webdriver2, and Driver create from capabilities", async () => {
await driver.startWithCapabilities(capabilities)
await By2.nativeName('One').click();
await driver.quit();
});
PageObject reduces the amount of duplicated code and easy to maintain.
PageObject
import { PageObject, By2 } from "selenium-appium";
class CalculatorPage extends PageObject {
isPageLoaded() {
return this.minusButton.isDisplayed();
}
get resultTextBox() { return By2.nativeAccessibilityId('CalculatorResults');}
get equalButton() { return By2.nativeAccessibilityId('equalButton'); }
get clearButton() { return By2.nativeName('Clear'); }
get plusButton() { return By2.nativeName('Plus'); }
get divideButton() { return By2.nativeAccessibilityId('divideButton'); }
get multiplyButton() { return By2.nativeXpath("//Button[@Name='Multiply by']") }
get minusButton() { return By2.nativeXpath("//Button[@AutomationId=\"minusButton\"]"); }
private async pressKeys(keys: string) {
for (var key of keys) {
await By2.nativeAccessibilityId('num' + key + 'Button').click();
}
}
async divid(a: string, b: string): Promise<string> {
await this.pressKeys(a);
await this.divideButton.click();
await this.pressKeys(b);
await this.equalButton.click();
return await this.getCalculatorResultText();
}
async multiply(a: string, b: string): Promise<string> {
await this.pressKeys(a);
await this.multiplyButton.click();
await this.pressKeys(b);
await this.equalButton.click();
return await this.getCalculatorResultText();
}
async plus(a: string, b: string): Promise<string> {
await this.pressKeys(a);
await this.plusButton.click();
await this.pressKeys(b);
await this.equalButton.click();
return await this.getCalculatorResultText();
}
async minus(a: string, b: string): Promise<string> {
await this.pressKeys(a);
await this.minusButton.click();
await this.pressKeys(b);
await this.equalButton.click();
return await this.getCalculatorResultText();
}
private async getCalculatorResultText(): Promise<string> {
return (await this.resultTextBox.getText()).replace('Display is', '').trim();
}
}
export default new CalculatorPage();
use the PageObject
beforeEach(async () => {
await CalculatorPage.waitForPageLoaded();
await CalculatorPage.clearButton.clear();
});
test('Addition', async () => {
// Find the buttons by their names and click them in sequence to perform 1 + 7 = 8
expect(await CalculatorPage.plus('1', '7')).toBe('8');
});
test('Division', async () => {
// Find the buttons by their accessibility ids and click them in sequence to perform 88 / 11 = 8
expect(await CalculatorPage.divid('88', '11')).toBe('8');
});
test('Multiplication', async () => {
// Find the buttons by their names using XPath and click them in sequence to perform 9 x 9 = 81
expect(await CalculatorPage.multiply('9', '9')).toBe('81');
});
test('Subtraction', async () => {
// Find the buttons by their accessibility ids using XPath and click them in sequence to perform 9 - 1 = 8
expect(await CalculatorPage.minus('9', '1')).toBe('8');
});
There are two global timers: waitforPageTimeout and waitforTimeout.
waitforTimeout is used by By2. When call any WebElement function of By2, it loops until the element is located
waitforPageTimeout is used by PageObject. It defined the default timeout for waitForPageLoaded.
Config.setWaitForPageTimeout(100);
expect(Config.getWaitForPageTimeout()).toBe(100);
Config.setWaitForTimeout(100);
expect(Config.getWaitForTimeout()).toBe(100);
driver.seleniumDriver returns the instance of actual WebDriver.
Because of typescript error, unlike By.name, By2 only replaced it with By2.name2.
selenium-appium projected is created when I prototype automation for react-native Windows testing. Appium is an open source, cross-platform test automation tool for native, hybrid and mobile web and desktop apps. We support simulators (iOS), emulators (Android), and real devices (iOS, Android, Windows, Mac).
Selenium is a browser automation library. Most often used for testing web-applications.
selenium-webdriver is the offical WebDriver Javascript binding from selenium project.
Although WebDriverIO provides webdriver for Appium, it has some restrictions:
Unfortunately selenium-webdriver doesn't support Mobile JSON Wire Protocol Specification. And that's why selenium-appium project is created.
To know more about how to integrate JavaScript test runner and WinAppDriver for UI automation, please refer to:
WinAppDriver + WebDriverIO example. Example to demostrate WinAppDriver and WebDriver integration without appium dependency
E2E test on React Native for Windows. MoreAboutE2ETest.md provides some background why React Native Windows choose WinAppDriver and node test runner for E2E testing.
winappdriver-js-webdriver-example, Which includes:
selenium-webdriver-winappdriver-example. An example of jest, selenium-webdriver and winappdriver integration
selenium-appium. selenium-appium is selenium-webdriver extension to make selenium-webdriver to drive Appium to run automation for native, hybrid and mobile web and desktop apps.
Choose the right E2E automation framework for React Native Windows
How to: Use Jest + selenium-webdriver + WinAppDriver to do Windows UI testing
Automated Windows UI testing by Jest + selenium-appium + selenium-webdriver + WinAppDriver
Inspecting UI Elements for WinAppDriver automation using Appium Desktop
The selenium-appium and all newly contributed code is provided under the MIT License.
FAQs
A selenium-webdriver extension to support native app testing by Mobile JSON Wire Protocol which appium supports, also provides easy wait for element for pages or navigation among pages, and supports PageObject pattern
The npm package selenium-appium receives a total of 2,664 weekly downloads. As such, selenium-appium popularity was classified as popular.
We found that selenium-appium demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.