appium-xcuitest-driver
Version:
Appium driver for iOS using XCUITest for backend
121 lines • 4.54 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const driver_1 = require("appium/driver");
const lodash_1 = __importDefault(require("lodash"));
const asyncbox_1 = require("asyncbox");
const utils_1 = require("../utils");
// these two constitute the wait after closing a window
const CLOSE_WINDOW_TIMEOUT = 5000;
const CLOSE_WINDOW_INTERVAL = 100;
const commands = {
/**
* @this {XCUITestDriver}
*/
async back() {
if (!this.isWebContext()) {
await this.nativeBack();
}
else {
await this.mobileWebNav('back');
}
},
/**
* @this {XCUITestDriver}
*/
async forward() {
if (!this.isWebContext()) {
}
await this.mobileWebNav('forward');
},
/**
* @this {XCUITestDriver}
*/
async closeWindow() {
if (!this.isWebContext()) {
throw new driver_1.errors.NotImplementedError();
}
// since the window will be closed and the execution context gone, return
// first before closing. Waiting for close will happen in the finally block
const script = `setTimeout(function () {window.open('','_self').close();}, 0); return true;`;
const context = this.curContext;
try {
return await this.executeAtom('execute_script', [script, []], true);
}
finally {
// wait for the window to successfully change...
try {
await (0, asyncbox_1.waitForCondition)(() => this.curContext !== context, {
waitMs: CLOSE_WINDOW_TIMEOUT,
intervalMs: CLOSE_WINDOW_INTERVAL,
});
}
catch {
this.log.debug('Context has not yet been changed after closing window. Continuing...');
}
}
},
/**
* Opens the given URL with the default application assigned to handle it based on the URL
* scheme, or the application provided as an optional parameter
*
* (Note: the version of Xcode must be 14.3+ and iOS must be 16.4+)
*
* @param {string} url - the URL to be opened, e.g. `myscheme://yolo`
* @param {string} [bundleId] - the application to open the given URL with. If not provided, then
* the application assigned by the operating system to handle URLs of the appropriate type
* @returns {Promise<void>}
* @since 4.17
* @this {XCUITestDriver}
*/
async mobileDeepLink(url, bundleId) {
return await this.proxyCommand('/url', 'POST', {
url,
bundleId,
});
},
};
const helpers = {
/**
* @this {XCUITestDriver}
*/
async nativeBack() {
if ((0, utils_1.isTvOs)(this.opts.platformName)) {
this.log.debug(`Sending Menu button as back behavior in tvOS`);
return await this.mobilePressButton('Menu');
}
try {
let navBar = await this.findNativeElementOrElements('class name', 'XCUIElementTypeNavigationBar', false);
let buttons = await this.findNativeElementOrElements('class name', 'XCUIElementTypeButton', true, navBar);
if (buttons?.length === 0) {
throw new Error('No buttons found in navigation bar');
}
let backButton = lodash_1.default.filter(buttons, (value) => value.label === 'Back')[0];
if (backButton) {
this.log.debug(`Found navigation bar 'back' button. Clicking.`);
}
else {
this.log.debug(`Unable to find 'Back' button. Trying first button in navigation bar`);
backButton = buttons?.[0];
}
await this.nativeClick(/** @type {string} */ (backButton));
}
catch (err) {
this.log.error(`Unable to find navigation bar and back button: ${err.message}`);
}
},
};
exports.default = { ...helpers, ...commands };
/**
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
*/
/**
* @typedef {Object} DeepLinkOptions
* @property {string} url The URL to be opened. This parameter is manadatory
* @property {string?} bundleId The bundle identifier of an application to open the
* given url with. If not provided then the default application for the given url scheme
* is going to be used.
*/
//# sourceMappingURL=navigation.js.map