我正在尝试为我的应用程序设置 webview 自动化,该应用程序作为混合应用程序在 Android 和 iOS 设备中运行(用 React Native0 编写)
运行我的自动化代码时我正在尝试使用
切换网络视图
const webviewName = `WEBVIEW_${packageName}`;
await driver.switchContext(webviewName);
在 Android 14 设备中,它切换到 webview 并按预期执行下一行工作。当我在 Android 13、15 设备中再次运行相同的操作时,即使 webview 处于活动状态,它也无法切换到 webview 上下文。
我从github上获取了这段代码
/**
* Custom implementation to switch to a webview for Android and iOS
*/
async switchToContext({ context, title, url }: { context: ContextType, title?: string, url?: string }) {
if (context === CONTEXT_REF.NATIVE_APP) {
return driver.switchContext(CONTEXT_REF.NATIVE_APP);
}
// Title and url are optional, but if they are provided we can use them to find the correct webview.
// We can't only rely on the context name due to the fact that we can have multiple webviews which
// could have different titles/urls
if (!title && !url) {
console.warn('\nTo get the best result, provide a title and, or url which will be used to find the correct webview. The more information the bigger the chance it will find the correct webview.\n');
}
// Get the contexts with our custom method
const currentContexts = await this.getCurrentContexts();
let matchingContext;
let packageName;
// This is where the magic happens, we are going to find the correct context(pae) to switch to for iOS or Android.
if (driver.isIOS) {
matchingContext = this.findMatchingContext({ contexts: currentContexts, identifier: BUNDLE_ID, title, url });
} else {
packageName = await driver.getCurrentPackage();
// 1. To find the correct webview page for Android we need to switch to the webview first
const webviewName = `WEBVIEW_${packageName}`;
**await driver.switchContext(webviewName);**
// 2. Now we need to find the correct page inside the webview
matchingContext = this.findMatchingContext({ contexts: currentContexts, identifier: packageName, title, url });
}
if (!matchingContext) {
throw new Error(this.generateNonMatchingErrorMessage({
identifier: driver.isIOS ? BUNDLE_ID :
packageName as string,
title,
url,
}));
}
// For iOS we can just use the `driver.switchContext` method to switch to the webview,
// but for Android we are already in the webview. We now need to switch to the correct page inside the webview
const switchFunction = driver.isIOS ? driver.switchContext.bind(driver) : driver.switchToWindow.bind(driver);
// Now switch to the correct context
return switchFunction(matchingContext.id);
}
我从 github 获取到 webview 自动化的参考项目:
https://github.com/webdriverio/appium-boilerplate/blob/main/tests/helpers/WebView.ts
我在 Android 13 和 15 设备上的错误:
[0-0] 2024-10-25T08:06:48.075Z INFO webdriver: COMMAND switchContext("WEBVIEW_com.example.app”)
[0-0] 2024-10-25T08:06:48.075Z INFO webdriver: [POST] http://127.0.0.1:4445/session/f2afefe4-a523-454c-86ce-26cba6135245/context
[0-0] 2024-10-25T08:06:48.075Z INFO webdriver: DATA { name: 'WEBVIEW_com.example.app' }
[0-0] Error of test: Error: waitUntil condition failed with the following reason: WebDriverError: This operation was aborted when running "context" with method "POST" and args "{"name":"WEBVIEW_com.example.app"}"
] at <anonymous> (/Users/vk/login/mobile-automation/node_modules/webdriverio/build/index.js:4684:11)
[0-0] at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
[0-0] at async Browser.wrapCommandFn (/Users/vk/login/mobile-automation/node_modules/@wdio/utils/build/index.js:1380:23)
[0-0] at async WebView.switchToContext (/Users/vk/login/mobile-automation/source/webview.ts:175:9)
[0-0] at async WebView.waitForWebsiteLoaded (/Users/vk/login/mobile-automation/source/webview.ts:320:9)
[0-0] at async UserContext.<anonymous> (/Users/vk/login/mobile-automation/source/specs/tests//sign-in-test.spec.ts:40:13)
[0-0] at async UserContext.executeAsync (/Users/vk/login/mobile-automation/node_modules/@wdio/utils/build/index.js:1500:20)
[0-0] at async UserContext.testFrameworkFnWrapper (/Users/vk/login/mobile/node_modules/@wdio/utils/build/index.js:1571:14)
this.getCurrentContexts()
重新调整的列表并检查WebView名称实际上是什么。