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

chore: Improve web view detection error messages #2452

Merged
merged 9 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
64 changes: 31 additions & 33 deletions lib/commands/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ 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 @@ -60,11 +57,37 @@ const extensions = {
(/** @type {RemoteDebugger} */ (this.remote)).cancelPageLoad();
return;
}
throw new Error(
`No webview has been detected after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms. ` +
`You may try to change the 'webviewConnectTimeout' or 'webviewConnectRetries' ` +
`capability values to modify the timeout.`
);
const appDict = (/** @type {RemoteDebugger} */ (this.remote)).appDict;
const errSuffix = `Make sure your web application is debuggable ` +
`and could be inspected in Safari Web Inspector.`;
if (_.isEmpty(appDict)) {
throw new Error(
`The remote debugger did not return any connected web applications after ` +
`${timer.getDuration().asMilliSeconds.toFixed(0)}ms. ` +
`${errSuffix} ` +
`You may try to change the 'webviewConnectTimeout' capability value to ` +
`customize the retrieval timeout.`
);
}
const errSuffix2 = `${errSuffix} You may try to change the 'webviewConnectRetries' ` +
`capability value to customize the amount of pages retrieval retries.`;
const appsWithPages = _.values(appDict).filter(({pageArray}) => !_.isEmpty(pageArray));
if (appsWithPages.length > 0) {
throw new Error(
`The remote debugger returned ${util.pluralize('web application', appsWithPages.length, true)} ` +
`with pages after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms, ` +
`although none of them matched our page search criteria. ${errSuffix2}`
);
} else {
const restartSuffix = this.isRealDevice()
? `Also, in rare cases the device restart may fix this issue if none of the above advices helps.`
: '';
throw new Error(
`The remote debugger returned ${util.pluralize('web application', _.size(appDict), true)}, ` +
`but none of them had pages after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms. ` +
`${errSuffix2} ${restartSuffix}`
);
}
},
/**
* @this {XCUITestDriver}
Expand Down Expand Up @@ -109,31 +132,6 @@ const extensions = {
`and 500ms interval between each retry. Consider customizing the value of 'webviewConnectRetries' ` +
`capability to change the amount of retries.`
);
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;
}
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);
},
/**
Expand Down
27 changes: 7 additions & 20 deletions lib/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ import {
normalizePlatformVersion,
printUser,
removeAllSessionWebSocketHandlers,
translateDeviceName,
shouldSetInitialSafariUrl,
translateDeviceName,
} from './utils';
import { AppInfosCache } from './app-infos-cache';

Expand Down Expand Up @@ -266,12 +266,6 @@ 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 @@ -321,8 +315,6 @@ 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 @@ -424,12 +416,7 @@ export class XCUITestDriver extends BaseDriver {
this.validateDesiredCaps({...caps, ...this.cliArgs});
}

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

// merge server capabilities + desired capabilities
caps = Object.assign({}, defaultServerCaps, caps);
Expand Down Expand Up @@ -668,11 +655,11 @@ export class XCUITestDriver extends BaseDriver {
await this.activateRecentWebview();
}
if (this.isSafari()) {
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`,
);
if (shouldSetInitialSafariUrl(this.opts)) {
this.log.info(`About to set the initial Safari URL to '${this.getCurrentUrl()}'`);
if (_.isNil(this.opts.safariInitialUrl) && !_.isNil(this.opts.initialDeeplinkUrl)) {
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
this.log.info(`Use the 'safariInitialUrl' capability to customize it`);
};
await this.setUrl(this.getCurrentUrl());
} else {
const currentUrl = await this.getUrl();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"appium-idb": "^1.6.13",
"appium-ios-device": "^2.5.4",
"appium-ios-simulator": "^6.1.7",
"appium-remote-debugger": "^12.0.3",
"appium-remote-debugger": "^12.1.1",
"appium-webdriveragent": "^8.9.1",
"appium-xcode": "^5.1.4",
"async-lock": "^1.4.0",
Expand Down
Loading