7

How can I switch to an IFrame with Codeception using ID? Actually I can use the name of the IFrame but not the ID -> Codeception SwitchToIFrame

IFrame Example:

<iframe id="iframeToolbar" src="link" frameborder="0" style="position: fixed; left: 0px; top: 0px; z-index: 998; width: 940px;" scrolling="no" width="100px" height="100%"></iframe>

Codeception Example:

<?php
# switch to iframe
$I->switchToIFrame("another_frame");
# switch to parent page
$I->switchToIFrame();

Is it maybe a Codeception <-> Facebook Webdriver Connection Problem?

EDIT: I reinstalled Codeception, followed the Quick Step Guide. Result - the Problem is still the same: Codeception and the Facebook Webdriver doesn't want to work together. My Codeception Code

acceptance.suite.yml:

actor: AcceptanceTester
modules:
  enabled:
    - \Helper\Acceptance
    - WebDriver:
            url: https://xxxxxxxxxxxxxx.com
            browser: chrome
            window_size: maximize
            clear_cookies: true

codeception.yml:

paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
extensions:
enabled:
    - Codeception\Extension\RunFailed
settings:
colors: true
  • OS: Windows 10
  • PHP: 7.1.7
  • PHPUnit: 6.4.4
  • Selenium Server: 3.8.1
  • Codeception: 2.3.7
  • Chrome: 63.0.3239.108
eknej
  • 85
  • 1
  • 10
  • Have you tried? Actually it should work, because it goes down to this method which says "name or id" -> https://github.com/facebook/php-webdriver/blob/62223d89bcdd4f755a62b2fbc193122e880c41fc/lib/Remote/RemoteTargetLocator.php#L58-L72 – Naktibalda Dec 19 '17 at 17:54
  • Yes you're right, but the switchToIFrame Method is linked to AcceptanceTesterActions.php and in this file is written on Line 2524: public function switchToIFrame($name = null) { return $this->getScenario()->runStep(new \Codeception\Step\Action('switchToIFrame', func_get_args())); } – eknej Dec 20 '17 at 10:02
  • so what? you are looking at the very surface. – Naktibalda Dec 20 '17 at 13:57
  • The Problem is that Codeception doesn't link to the Facebook Webdriver. They don't know each other. How can I connect this two Libraries? – eknej Dec 20 '17 at 14:32
  • I'm sure that it does, nothing would work if they weren't connected. – Naktibalda Dec 20 '17 at 14:44
  • On this [Image](https://i.stack.imgur.com/ka5PN.png) you can see some works some do not. – eknej Dec 20 '17 at 15:31
  • This is a completely different issue. Most likely cause is that WebDriver is not enabled in this suite. If it is, then running codecept build should fix the issue. – Naktibalda Dec 20 '17 at 16:53
  • Is the problem that chromedriver is not running at all? And, getting the 'method not found' warning in PHPStorm doesn't necessarily mean that something is wrong with the code, it could also be with the PHPStorm setup. – Aaron Wallentine Jan 06 '18 at 03:04

2 Answers2

9

I had this issue, testing a page with a Google reCaptcha in it ... the reCaptcha is in its own iframe, and since that iframe is generated by 3rd-party code, we have no control over its name attribute (at least when it's first generated).

What I ended up doing was running a javascript snippet which can find the iframe based on other things, and then giving it an id, so that Codeception Webdriver could switch to it:

    public function _clickOnCaptcha(AcceptanceTester $I)
{
    // give the recaptcha iframe a name so codeception webdriver can switch to it
    $recaptcha_frame_name = 'recaptcha-frame';
    $I->executeJS("$('.g-recaptcha iframe').attr('name', '$recaptcha_frame_name')");
    $I->switchToIFrame($recaptcha_frame_name);
    $I->see('not a robot');
    $I->seeElement('.rc-anchor');
    $I->click(['id' => 'recaptcha-anchor']);
    $I->switchToIFrame(); // switch back to main window
}

I did have control over the containing elements, so in this case, it's contained within an element with class g-recaptcha ... so we use jquery to find the iframe inside that element: $('.g-recaptcha iframe'), and then give it a name attribute: .attr('name', '$recaptcha_frame_name').

Then we can use Codeception to switch to it and click the captcha checkbox: $I->switchToIFrame($recaptcha_frame_name); $I->click(['id' => 'recaptcha-anchor']);

Then, when we're done, switch back out to the main frame so we can submit our form: $I->switchToIFrame(); // switch back to main window

NB, I'm using the reCaptcha test keys, as specified here, in the testing environment so that it will never actually ask to solve a captcha.

https://developers.google.com/recaptcha/docs/faq

With the following test keys, you will always get No CAPTCHA and all verification requests will pass.

Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe The reCAPTCHA widget will show a warning message to claim that it's only for testing purposes. Please do not use these keys for your production traffic.

Aaron Wallentine
  • 2,318
  • 24
  • 22
  • For cases where no JQuery is available, and presuming there is only 1 iframe to target: `document.getElementsByTagName('iframe')[0].setAttribute('name', '$frameName')` – Thomas Vangelooven May 12 '20 at 10:00
0

First of all, in your case the problem might be that you're not calling the acceptance tester. You should start your script with this:

<?php
$I = /*am a */ new AcceptanceTester($scenario);

Now to get into an IFrame in Codeception using the WebDriver:

You just have to name the IFrame in a string, using EITHER the ID or the name. Here is an example:

There is a page with the IFrame:

<iframe name = "IFrameByName" id = "IFrameByID" width = "500" height = "300" src = "https://messagetothefish.com"></iframe>

This IFrame contains the string, "No one knows who discovered water" but the parent frame does not. I tested this Cept with PhantomJS and Selenium.

<?php

$I = /*am a */ new AcceptanceTester($scenario);

$I->wantTo('See how Iframes work');
$I->amOnUrl("https://wordpress-bdd.com/codeception-iframe/");
$I->dontSee("No one knows who discovered water");

//Switch by name
$I->switchToIFrame("IFrameByName");
$I->see("No one knows who discovered water");

//switch back to parent
$I->switchToIFrame();
$I->dontSee("No one knows who discovered water");

//Switch by ID
$I->switchToIFrame("IFrameByID");
$I->see("No one knows who discovered water");
$I->dontSee('Lorum Ipsum');

//switch back to parent
$I->switchToIFrame();
$I->dontSee("No one knows who discovered water");

Codeception Screenshot

John Dee
  • 539
  • 4
  • 14
  • I just want to switch to an Iframe by using ID. When I use $I->click('#ID'); codeception finds the Iframe, there is no problem (and clicks). But in the next step codeception can't find the element, when I want to click a element in this Frame -because I didn't change to the Frame. I revised my Post with the needed informations. – eknej Jan 02 '18 at 15:20