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: wait for wda start in sim as well for preinstalled wda start #876

Merged
merged 12 commits into from
Mar 28, 2024
80 changes: 56 additions & 24 deletions lib/webdriveragent.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,57 @@ class WebDriverAgent {
* }
* }
*
* @return {Promise<any?>} State Object
* @param {number} [timeoutMs=0] If the given timeoutMs is zero or negative number,
* this function will return the response of `/status` immediately. If the given timeoutMs,
* this function will try to get the response of `/status` up to the timeoutMs.
* @return {Promise<import('@appium/types').StringRecord|null>} State Object
* @throws {Error} If there was an error within timeoutMs timeout.
* No error is raised if zero or negative number for the timeoutMs.
*/
async getStatus () {
async getStatus (timeoutMs = 0) {
const noSessionProxy = new NoSessionProxy({
server: this.url.hostname,
port: this.url.port,
base: this.basePath,
timeout: 3000,
});
try {
return await noSessionProxy.command('/status', 'GET');
} catch (err) {

const getStatus = async () => await /** @type import('@appium/types').StringRecord */ (noSessionProxy.command('/status', 'GET'));

if (_.isNull(timeoutMs) || timeoutMs <= 0) {
try {
return await getStatus();
} catch (err) {
this.log.debug(`WDA is not listening at '${this.url.href}'`);
return null;
}
}

let status = null;
let lastError = null;
await waitForCondition(async () => {
try {
status = await getStatus();
return true;
} catch (err) {
lastError = err;
return false;
}
}, {
waitMs: this.wdaLaunchTimeout,
intervalMs: 300,
});

if (status) {
return status;
}

if (lastError) {
this.log.debug(`WDA is not listening at '${this.url.href}'`);
return null;
throw lastError;
}

return null;
}

/**
Expand Down Expand Up @@ -317,28 +353,14 @@ class WebDriverAgent {
await this.device.devicectl.launchApp(
this.bundleIdForXctest, { env, terminateExisting: true }
);

// Launching app via decictl does not wait for the app start.
// We should wait for the app start by ourselves.
try {
await waitForCondition(async () => !_.isNull(await this.getStatus()), {
waitMs: this.wdaLaunchTimeout,
intervalMs: 300,
});

} catch (err) {
throw new Error(
`Failed to start the preinstalled WebDriverAgent in ${this.wdaLaunchTimeout} ms. ` +
`The WebDriverAgent might not be properly built or the device might be locked. ` +
`The 'appium:wdaLaunchTimeout' capability modifies the timeout.`
);
}
}

/**
* Launch WDA with preinstalled package without xcodebuild.
* @param {string} sessionId Launch WDA and establish the session with this sessionId
* @return {Promise<any?>} State Object
* @return {Promise<import('@appium/types').StringRecord|null>} State Object
* @throws {Error} If there was an error within timeoutMs timeout.
* No error is raised if zero or negative number for the timeoutMs.
*/
async launchWithPreinstalledWDA(sessionId) {
const xctestEnv = {
Expand Down Expand Up @@ -371,7 +393,17 @@ class WebDriverAgent {
}

this.setupProxies(sessionId);
const status = await this.getStatus();
let status;
try {
status = await this.getStatus(this.wdaLaunchTimeout);
} catch (err) {
this.log.debug(`Failed to get the status. Error ${err.message}`);
throw new Error(
`Failed to start the preinstalled WebDriverAgent in ${this.wdaLaunchTimeout} ms. ` +
`The WebDriverAgent might not be properly built or the device might be locked. ` +
`The 'appium:wdaLaunchTimeout' capability modifies the timeout.`
);
}
this.started = true;
return status;
}
Expand Down
Loading