I am creating automated tests for an iOS app that uses WKWebviews to
display some data. The user types a query into a native text field and
results are displayed inside the webview. The problem is that I got
inconsistent behaviour when checking some expected structure in the
HTML.
Here is the HTML I am expecting:
<div id="results">
<div class="frame">
<div class="card">
// here my data
</div>
</div>
</div>
In Appium I check the very simple case that these three divs exist as the follows:
it("should display results inside the web view", function () {
return driver
.waitForElementByName("Address and Search")
.sendKeys("search query")
.sleep(1000)
.contexts().then(function (contexts) { // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
return driver.context(contexts[1]); // choose the webview context
})
.waitForElementById("results", 60000)
.waitForElementByCss(".frame", 60000)
.waitForElementByCss(".card", 60000)
.sleep(3000)
});
Every time I run the test I get different results: sometimes it finds
all elements, and sometimes it find only the first element (waitForElementById), then fails to get any further elements, and sometimes it couldn’t find any element
First run:
1) ios simple should work with WEBVIEW:
Error: [waitForElementById("results",60000)] Element condition wasn't satisfied!
Second run
1) ios simple should work with WEBVIEW:
Error: [waitForElementByCss(".frame",60000)] Element condition wasn't satisfied!
Third run:
POST /session/:sessionID/elements {“using”:“id”,“value”:“results”}
RESPONSE elements(“id”,“results”) [{“ELEMENT”:“5000”}]
RESPONSE waitForElementById(“results”,60000) {“ELEMENT”:“5000”}
CALL waitForElementByCss(“.frame”,60000)
CALL elements(“css selector”,“.frame”)
POST /session/:sessionID/elements {“using”:“css selector”,“value”:“.frame”}
RESPONSE elements(“css selector”,“.frame”) [{“ELEMENT”:“5001”}]
RESPONSE waitForElementByCss(“.frame”,60000) {“ELEMENT”:“5001”}
CALL waitForElementByCss(“.card”,60000)
CALL elements(“css selector”,“.card”)
POST /session/:sessionID/elements {“using”:“css selector”,“value”:“.card”}
RESPONSE elements(“css selector”,“.card”) [{“ELEMENT”:“5002”}]
RESPONSE waitForElementByCss(“.card”,60000) {“ELEMENT”:“5002”}
CALL element.sleep(3000)
RESPONSE element.sleep(3000)
✓ should work with WEBVIEW (10981ms)
Here is my configuration:
exports.ios93 = {
browserName: '',
'appium-version': '1.4.13',
platformName: 'iOS',
platformVersion: '9.3',
deviceName: 'iPhone 6',
app: undefined // will be set later
};
I tried to solve the problem by doing the following:
Adding delay after switching to WEBVIEW as follows:
.context('WEBVIEW_1')
.sleep(25000)
Changing the window as follows:
.context('WEBVIEW_1')
.windowHandles()
.then(function(handles) {
driver.window(handles[handles.length-1])
})
but this didn’t have any effect.
Note that the Android version of the app does not have all these problems when testing with Appium.