0

I have tried every means, three browsers (Chrome, FireFox, Edge), Trying to use WebDriverIO to locate objects within an iframe has failed. Especially for testing it, I wrote the simplest html

outer.html

<html>
  <body>
    <iframe id="zzz" src="zzz.html" height="150" />
  </body>
</html>

zzz.html

<input id="foo" name="ccc" value="ccc" />

my code

await browser.url(`http://localhost:8080/.../outer.html`)

const $iframe = await browser.$('iframe#zzz');
$iframe.waitForExist({ timeout: 10000 });
console.log('iframe exists');

const documentReady = await browser.executeScript('return document.readyState;', []);
console.log('Document ready state:', documentReady);

await browser.waitUntil(
    async () => (await browser.execute(() => document.readyState)) === 'complete',
    { timeout: 10000, timeoutMsg: 'iframe load fail' }
);

await browser.pause(10000);
await browser.switchToFrame($iframe);
browser.setTimeout({ 'implicit': 10000 })
console.log('switch to iframe');

let fooExist = await browser.executeScript(
    'return document.getElementById("foo")!=null;', []);
console.log('found foo by browser.executeScript:', fooExist);

fooExist = await browser.execute(() => {
    return document.getElementById("foo") != null;
});
console.log('found foo by browser.execute:', fooExist);

fooExist = await (await browser.$('#foo')).isExisting();
console.log("found foo by $('#foo'):", fooExist);

await browser.switchToParentFrame();

result

[0-0] iframe exists
[0-0] Document ready state: complete
[0-0] switch to iframe
[0-0] found foo by browser.executeScript: true
[0-0] found foo by browser.execute: false
[0-0] found foo by $('#foo'): false

Currently only browser.executeScript(..) can find the foo object, I would like $('#foo') and browser.execute(..) to work as well.

1 Answer 1

0

I'm sorry to say that but it's hard to figure it out from your code.

You do many actions here, maybe some of them unnecessary and providing side effects.

  1. Don't use $ in a variable name. Common advise from google styleguide. Here it's even more confusing because $ stands for command in webdriver-io.

  2. You missed await before $iframe.waitForExist({ timeout: 10000 });

  3. You finding iframe and wait for it to exist and then wait to page loaded. It should be vice versa order.

const documentReady = await browser.executeScript('return document.readyState;', []);
console.log('Document ready state:', documentReady);

await browser.waitUntil(
    async () => (await browser.execute(() => document.readyState)) === 'complete',
    { timeout: 10000, timeoutMsg: 'iframe load fail' }
);

const iframe = await browser.$('iframe#zzz');
await iframe.waitForExist({ timeout: 10000 });
console.log('iframe exists');
  1. I don't understand why you have browser.setTimeout({ 'implicit': 10000 }). Try to remove it.

  2. Try to split finding foo and waiting for it to exist.

const foo = await browser.$('#foo');
fooExist = await foo.isExisting();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.