Skip to content

Commit

Permalink
chore: Try to open the initial URL with WDA if no active pages are fo…
Browse files Browse the repository at this point in the history
…und (#2449)
  • Loading branch information
mykola-mokhnach authored Aug 8, 2024
1 parent 7068c81 commit 08cad3e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 30 deletions.
67 changes: 51 additions & 16 deletions lib/commands/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ import {errors, isErrorType} from 'appium/driver';
import {util, timing} from 'appium/support';
import IOSPerformanceLog from '../device-log/ios-performance-log';
import _ from 'lodash';
import { isIos17OrNewer, shouldSetInitialSafariUrl } from '../utils';
import { SAFARI_BUNDLE_ID } from '../app-utils';

const NATIVE_WIN = 'NATIVE_APP';
const WEBVIEW_WIN = 'WEBVIEW';
const WEBVIEW_BASE = `${WEBVIEW_WIN}_`;
const DEFAULT_REMOTE_DEBUGGER_CONNECT_TIMEOUT_MS = 5000;
const DEFAULT_LIST_WEB_FRAMES_RETRIES = 20;
const DEFAULT_URL_LOAD_TIMEOUT_MS = 15 * 1000;


const extensions = {
Expand Down Expand Up @@ -76,30 +80,61 @@ const extensions = {
if (!this.remote) {
await this.connectToRemoteDebugger();
}
/** @type {number|undefined} */
const doListPages = async (/** @type {number} */ retries) => {
try {
const pageArray = await (/** @type {RemoteDebugger} */ (this.remote)).selectApp(
shouldFilterByUrl ? this.getCurrentUrl() : undefined,
retries,
this.opts.ignoreAboutBlankUrl,
);
if (_.isEmpty(pageArray)) {
// we have no web frames, but continue anyway
this.log.debug(`No web frames found after ${util.pluralize('retry', retries, true)}`);
}
return pageArray;
} catch (err) {
this.log.debug(
`No available web pages after ${util.pluralize('retry', retries, true)}: ${err.message}`
);
return [];
}
};

/** @type {number} */
const maxRetriesCount = _.isInteger(this.opts.webviewConnectRetries)
? Math.max(/** @type {number} */ (this.opts.webviewConnectRetries), 1)
: undefined;
: DEFAULT_LIST_WEB_FRAMES_RETRIES;
this.log.debug(
`About to select a web application with ${util.pluralize('retry', maxRetriesCount ?? 20, true)} ` +
`About to select a web application with ${util.pluralize('retry', maxRetriesCount, true)} ` +
`and 500ms interval between each retry. Consider customizing the value of 'webviewConnectRetries' ` +
`capability to change the amount of retries.`
);
try {
const pageArray = await (/** @type {RemoteDebugger} */ (this.remote)).selectApp(
shouldFilterByUrl ? this.getCurrentUrl() : undefined,
maxRetriesCount,
this.opts.ignoreAboutBlankUrl,
);
if (_.isEmpty(pageArray)) {
// we have no web frames, but continue anyway
this.log.debug('No web frames found.');
if (
this._isStartingSession && !this._didOpenInitialSafariUrlViaWda
&& this.isSafari()
&& isIos17OrNewer(this.opts)
&& shouldSetInitialSafariUrl(this.opts)
) {
const halfRetries = Math.ceil(maxRetriesCount / 2);
const pages = await doListPages(halfRetries);
if (!_.isEmpty(pages)) {
return pages;
}
return pageArray;
} catch (err) {
this.log.debug(`No available web pages: ${err.message}`);
return [];
this.log.debug(`No active pages have been detected after ${util.pluralize('retry', halfRetries, true)}`);
this.log.debug(`Opening ${this.getCurrentUrl()} in Safari to continue with the lookup`);
try {
await this.proxyCommand('/url', 'POST', {
url: this.getCurrentUrl(),
bundleId: SAFARI_BUNDLE_ID,
idleTimeoutMs: DEFAULT_URL_LOAD_TIMEOUT_MS,
});
this._didOpenInitialSafariUrlViaWda = true;
} catch (e) {
this.log.warn(e.message);
}
return await doListPages(halfRetries);
}
return await doListPages(maxRetriesCount);
},
/**
* @this {XCUITestDriver}
Expand Down
5 changes: 3 additions & 2 deletions lib/commands/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {services} from 'appium-ios-device';
import {errors} from 'appium/driver';
import {util} from 'appium/support';
import {AuthorizationStatus} from './enum';
import { isIos17OrNewer } from '../utils';

export default {
/**
Expand All @@ -25,7 +26,7 @@ export default {
async getGeoLocation() {
// Currently we proxy the setGeoLocation to mobile:setSimulatedLocation for iOS 17+.
// It would be helpful to address to use "mobile:getSimulatedLocation" for iOS 17+.
if (this.opts.platformVersion && util.compareVersions(this.opts.platformVersion, '>=', '17.0')) {
if (isIos17OrNewer(this.opts)) {
const {latitude, longitude} = await this.mobileGetSimulatedLocation();
if (latitude && longitude) {
this.log.debug('Returning the geolocation that has been previously set by mobile:setSimulatedLocation. ' +
Expand Down Expand Up @@ -81,7 +82,7 @@ export default {
return /** @type {Location} */ ({latitude, longitude, altitude: 0});
}

if (this.opts.platformVersion && util.compareVersions(this.opts.platformVersion, '>=', '17.0')) {
if (isIos17OrNewer(this.opts)) {
this.log.info(`Proxying to mobile:setSimulatedLocation method for iOS 17+ platform version`);
await this.mobileSetSimulatedLocation(latitude, longitude);
} else {
Expand Down
27 changes: 16 additions & 11 deletions lib/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
printUser,
removeAllSessionWebSocketHandlers,
translateDeviceName,
shouldSetInitialSafariUrl,
} from './utils';
import { AppInfosCache } from './app-infos-cache';

Expand Down Expand Up @@ -265,6 +266,12 @@ export class XCUITestDriver extends BaseDriver {
/** @type {import('appium-remote-debugger').RemoteDebugger|null} */
remote;

/** @type {boolean} */
_didOpenInitialSafariUrlViaWda;

/** @type {boolean} */
_isStartingSession;

/**
*
* @param {XCUITestDriverOpts} opts
Expand Down Expand Up @@ -314,6 +321,8 @@ export class XCUITestDriver extends BaseDriver {
this._audioRecorder = null;
this.appInfosCache = new AppInfosCache(this.log);
this.remote = null;
this._didOpenInitialUrlViaWda = false;
this._isStartingSession = false;
}

async onSettingsUpdate(key, value) {
Expand Down Expand Up @@ -415,7 +424,12 @@ export class XCUITestDriver extends BaseDriver {
this.validateDesiredCaps({...caps, ...this.cliArgs});
}

await this.start();
this._isStartingSession = true;
try {
await this.start();
} finally {
this._isStartingSession = false;
}

// merge server capabilities + desired capabilities
caps = Object.assign({}, defaultServerCaps, caps);
Expand Down Expand Up @@ -654,7 +668,7 @@ export class XCUITestDriver extends BaseDriver {
await this.activateRecentWebview();
}
if (this.isSafari()) {
if (shouldSetInitialSafariUrl(this.opts)) {
if (shouldSetInitialSafariUrl(this.opts) && !this._didOpenInitialSafariUrlViaWda) {
this.log.info(
`About to set the initial Safari URL to '${this.getCurrentUrl()}'.` +
`Use 'safariInitialUrl' capability in order to customize it`,
Expand Down Expand Up @@ -2154,15 +2168,6 @@ export class XCUITestDriver extends BaseDriver {
mobileStopXctestScreenRecording = commands.xctestRecordScreenExtensions.mobileStopXctestScreenRecording;
}

/**
* @param {XCUITestDriverOpts} opts
* @returns {boolean}
*/
function shouldSetInitialSafariUrl(opts) {
return !(opts.safariInitialUrl === '' || (opts.noReset && _.isNil(opts.safariInitialUrl)))
&& !opts.initialDeeplinkUrl;
}

export default XCUITestDriver;

/**
Expand Down
17 changes: 17 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,23 @@ export function normalizePlatformName(platformName) {
return isTvOs(platformName) ? PLATFORM_NAME_TVOS : PLATFORM_NAME_IOS;
}

/**
* @param {import('./driver').XCUITestDriverOpts} opts
* @returns {boolean}
*/
export function shouldSetInitialSafariUrl(opts) {
return !(opts.safariInitialUrl === '' || (opts.noReset && _.isNil(opts.safariInitialUrl)))
&& !opts.initialDeeplinkUrl;
}

/**
* @param {import('./driver').XCUITestDriverOpts} opts
* @returns {boolean}
*/
export function isIos17OrNewer(opts) {
return !!opts.platformVersion && util.compareVersions(opts.platformVersion, '>=', '17.0');
}

export {
getAndCheckXcodeVersion,
getAndCheckIosSdkVersion,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"appium-ios-device": "^2.5.4",
"appium-ios-simulator": "^6.1.7",
"appium-remote-debugger": "^12.0.1",
"appium-webdriveragent": "^8.7.8",
"appium-webdriveragent": "^8.9.0",
"appium-xcode": "^5.1.4",
"async-lock": "^1.4.0",
"asyncbox": "^3.0.0",
Expand Down

0 comments on commit 08cad3e

Please sign in to comment.