Skip to content
This repository has been archived by the owner on Nov 29, 2018. It is now read-only.

SwitchTo losing context when using a frame id #4876

Closed
lukeis opened this issue Mar 4, 2016 · 23 comments
Closed

SwitchTo losing context when using a frame id #4876

lukeis opened this issue Mar 4, 2016 · 23 comments

Comments

@lukeis
Copy link
Member

lukeis commented Mar 4, 2016

Originally reported on Google Code with ID 4876

When I use SwitchTo().Frame("...") to switch focus to a frame in my application, it
will work for one or several more lines of code but will then fail because focuses
shifts back to the hosting page.  I know that focus has shifted back to the hosting
page because I can execute code in Visual Studio debugger that shows that elements
in the host page can be found but not elements in the child iframe.  The weird thing
is, it is inconsistent how long the SwitchTo() works.  Some times it only works for
one more call to findElement.  Sometimes it works for two more calls to FindElement.
 It is completely random.

    driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
    driver.SwitchTo().Frame("ctl00_iFrameMedtox"); iframe automatically like ide can
    driver.FindElement(By.Id("ctl00_Side1_hlHome")).Click(); //works

    if (driver.FindElements(By.Id("ctl00_CPH1_LinkButtonUserCollectionSite")).Count !=
0) //sometimes works
    {
        driver.FindElement(By.Id("ctl00_CPH1_LinkButtonUserCollectionSite")).Click();
    }
    driver.FindElement(By.Id("ctl00_CPH1_rcbCollectionSites_Arrow")).Click();

If I add more driver.SwitchTo().Frame("") calls before the FindElement() calls, this
fixes things sometimes but not always because sometimes, focus in on the iframe and
sometimes focus is on the parent page.



I have found that the way to get around this is to call: 

    driver.SwitchTo().DefaultContent();
    driver.SwitchTo().Frame(0); 

Calling switchTo in this way works successfully.

I am using webdrive 2.27 for dotnet and visual studio 10 with firefox 17 on windows.

Reported by wongzhicheng on 2012-12-06 00:46:52

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Correction: it doesn't matter if you use a frame id or not.  Either way works.  What
causes the problem is not calling "driver.SwitchTo().DefaultContent();" first.

Reported by wongzhicheng on 2012-12-06 00:47:53

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I can confirm this as well.
Selenium: 2.27.0 (java)
Platform: Windows 7
Browser: FireFox 17.01 local (happened on FireFox 16+17 remote on saucelabs.com as
well).
This seems to be a regression from 2.25, where it didn't happen in our "real world
tests".

It seems like web driver is switching back to the top frame ("default content"), pretty
randomly during execution.

Here is some reproduction code:
<pre>
@Test
    public void testIframeBug() throws Exception {
        FirefoxDriver driver = new FirefoxDriver();
        driver.get("http://jsfiddle.net/xWFde/1/embedded/result/");
        //driver.switchTo().defaultContent();
        driver.switchTo().frame(0);
        for (int i = 0; i < 1000; i++) {
            String currentLocation = driver.executeScript("return window.location.href").toString();
            System.out.println(currentLocation);
            new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.id("inputText")));
            WebElement input = driver.findElementById("inputText");
            WebElement button = driver.findElementById("submitButton");
            input.clear();
            input.sendKeys("rand" + new Random().nextInt());
            button.click();
        }
        driver.quit();
    }

</pre>

Upon execution, I can see the following output:

http://fiddle.jshell.net/xWFde/1/show/light/ # this is the correct frame url
.. After about 10 iterations...
http://fiddle.jshell.net/xWFde/1/show/light/ # still is the correct frame url
http://jsfiddle.net/xWFde/1/embedded/result/ # changed to the top frame, and then the
test fails since the element could not be found


Reported by amitayd on 2012-12-09 13:30:32

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Another thing, the workaround doesn't work for me. The frame is still being switched
to the top one.
Ocassionaly I would get "org.openqa.selenium.StaleElementReferenceException: Element
belongs to a different frame than the current one - switch to its containing frame
to use it", depending on which stage of the test the frame switching occurred.

Reported by amitayd on 2012-12-09 13:37:50

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

While initially I thought this has something to do with the frame being reloaded (in
the test, by clicking a button which reloads the page), it seems it does while just
working on the same element.
Here is a simpler reproduction:

    @Test
    public void testIframeBug2() throws Exception {
        FirefoxDriver driver = new FirefoxDriver();
        driver.get("http://jsfiddle.net/xWFde/1/embedded/result/");
        driver.switchTo().frame(0);
        new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.id("inputText")));

        WebElement input = driver.findElementById("inputText");
        for (int i = 0; i < 20000; i++) {
            System.out.println(i);
            input.clear();
            input.sendKeys("rand" + new Random().nextInt());
        }
        driver.quit();
    }


I get the following exception after a few hundreds iterations:
(this time one firefox 16.02), on input.clear(), or input.sendKeys():


org.openqa.selenium.StaleElementReferenceException: Element belongs to a different
frame than the current one - switch to its containing frame to use it
Command duration or timeout: 23 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version:
'1.7.0_09'
Session ID: a566c0e4-d753-45b7-a660-572ad67f5893
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=XP, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true,
acceptSslCerts=true, handlesAlerts=true, browserName=firefox, browserConnectionEnabled=true,
nativeEvents=true, webStorageEnabled=true, rotatable=false, locationContextEnabled=true,
applicationCacheEnabled=true, takesScreenshot=true, version=16.0.2}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:246)
    at org.openqa.selenium.remote.RemoteWebElement.clear(RemoteWebElement.java:113)
    at _______________________.testIframeBug2(PlaygroundTests.java:142)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
    at org.testng.TestNG.run(TestNG.java:1031)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:111)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.openqa.selenium.remote.ErrorHandler$UnknownServerException: Element
belongs to a different frame than the current one - switch to its containing frame
to use it
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version:
'1.7.0_09'
Driver info: driver.version: unknown
    at <anonymous class>.<anonymous method>(resource://fxdriver/modules/web_element_cache.js:7210)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:6826)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:7535)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:10203)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:10222)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:10227)
    at <anonymous class>.<anonymous method>(file:///C:/Users/amitay/AppData/Local/Temp/anonymous8329289075880050169webdriver-profile/extensions/fxdriver@googlecode.com/components/command_processor.js:10167)

Process finished with exit code 0

Reported by amitayd on 2012-12-09 15:09:48

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Reported by barancev on 2012-12-09 19:36:45

  • Labels added: Browser-Firefox

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I investigated it further on the Selenium codebase, and some additional findings:
1) Could not reproduce it when native events are turned off (-Dselenium.browser.native_events=true)

2) What happens in the FireFox WebDriver extension is that in wdsession.js the weak
reference to the frame window (this.window_) set in setWindow() is gone, and the fail
over is being run:
  if (!win || !win.document) {
    // Uh-oh, we lost our DOM! Try to recover by changing focus to the
    // main content window.
    win = this.chromeWindow_.getBrowser().contentWindow;
    this.setWindow(win);
  }

This is an incorrect behaviour, since it switches to the default content window/
It might also happen in the code to resolve http://code.google.com/p/selenium/issues/detail?id=4309
(http://code.google.com/p/selenium/source/detail?r=17963) , which again, will not work
if we have set an active frame.

3) It seems like the revision to fix dereferenced frame window on http://code.google.com/p/selenium/source/detail?r=12196
is reducing the chance of it happening, but does not eliminate it. 

4) I am not sure why the native events code might cause (or increase chances of) this
behaviour.

5) I tried to find a way to get a persistent weak reference to a DOM node that will
not be removed, and setting the frame window by it. I found that using the frame element
seems to work. So if you keep the frame element (weakly) referenced, you can get the
window that is under it, using frame.contentWindow property.

I am attaching a patch file that implements the change. I have run the FrameSwitchingTest
successfully on firefox with nativeEvents on and off. 
I am new to the selenium project, so I am still not sure what I have to do to contribute
directly to the repository, and it is best some contributor will have a look at it
first.

Amitay

Reported by amitayd on 2012-12-10 01:40:24


- _Attachment: [selenium_frame_window_by_element.patch](https://storage.googleapis.com/google-code-attachments/selenium/issue-4876/comment-6/selenium_frame_window_by_element.patch)_

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Correction: The bug does occur with nativeEvents = false (firefox 17.01)
Test:

@Test
     public void testIframeBug2() throws Exception {
        FirefoxProfile profile = new FirefoxProfile();
        profile.setEnableNativeEvents(false);
        FirefoxDriver driver = new FirefoxDriver(profile);
        driver.get("http://jsfiddle.net/xWFde/1/embedded/result/");
        driver.switchTo().frame(0);
        new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.id("inputText")));

        for (int i = 0; i < 20000; i++) {
            try{
                new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.id("submitButton")));
                WebElement input = driver.findElementById("inputText");
                WebElement submit = driver.findElementById("submitButton");
                System.out.println(i);
                input.clear();
                input.sendKeys("rand" + new Random().nextInt());
                submit.click();
            } catch (Exception ex) {
                throw ex;
            } finally {
                System.out.println(driver.getCurrentUrl());
            }
        }
        driver.quit();
    }

Note that the url changes before the exception is being thrown.

Reported by amitayd on 2012-12-10 17:17:11

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I am experience this as well in testing of our Facebook app where it the test will just
loose focus of the frame being tested. Going back to 2.25.0 seems to fix this. Any
eta on when a patch for this might be pushed?

Reported by qablogmbox on 2012-12-18 14:47:09

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Did you try use the patch I provided? Might be a good confirmation for applying the
patch to verify that it fixes another case.
On 2.25.0 I think the same problems occurs too (maybe more rarely), but it can show
as "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) ", see http://code.google.com/p/selenium/issues/detail?id=4309
.

Reported by amitayd on 2012-12-18 21:49:25

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Yes I saw that same error when I reverted to 2.25 as well. How do I apply the patch.
Can you provide instructions. I am using the ruby selenium-webdriver gem but have no
idea and to apply the patch. 

Thanks in advance.

Reported by qablogmbox on 2012-12-18 22:04:11

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Does anyone know if there is a work around for this. At this point I basically cannot
test our facebook app in Friefox because of this and since 2.25 has its own issue rolling
back is not a option. Any help would be most greatly appreciated.

Reported by qablogmbox on 2012-12-19 21:43:46

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I was confronted with the same problem using 2.25.0 java webdriver using firefox 17.
However since I've downgraded back to Firefox 16 it works again.
Maybe this could be a solution for you until defect is fixed.

Alternatively you can download selenium sources (e.g. as described here http://code.google.com/p/selenium/source/checkout),
try to find/implement a bugfix/workaround so its working for your case.
If you would find a solution post it here, I would be interested! ;-)

Reported by david.badstuebner@xcom.de on 2012-12-20 07:20:02

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

David, please review the previous comment history. To summarize.
1) I was able to reproduce the problem in FireFox 16 and earlier versions (just more
rarely)
2) I have provided a patch and waiting for some contributor to pick it up and merge
it.


Reported by amitayd on 2012-12-20 19:03:21

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

This is happening for me as well in the Ruby bindings. A fix would be great!!!

Reported by x.bgoad@reverbnation.com on 2012-12-21 21:02:43

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I think this issue should be increased in priority as it makes reliable testing impossible.

Reported by jason.lunn on 2012-12-28 16:05:38

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Can't do automated testing with Firefox until this is fixed. :(

Reported by davidkwood on 2012-12-28 16:13:37

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Has anyone had a chance to review the patch in comment 6 above? If its good can we get
a patch build. Without this Firefox testing is non-functional for us. Thanks in advance.

Reported by qablogmbox on 2013-01-07 15:09:37

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

I have tried applying the patch to 2.28 and run the patched Selenium on a very large
set of tests using Firefox 17.0.1 ESR.  The dialog problem which was affecting about
10% of the tests appears fully fixed and there seem to be no adverse effects.  Including
this in a driver would be great as this has been a major problem.

Reported by mthtaylor on 2013-01-09 23:27:03

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Have any of the committers had a chance to review this patch. Based on the post above
it seems goods. 

Reported by qablogmbox on 2013-01-22 14:51:10

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

@amitayd: Would you please sign the CLA http://goo.gl/qC50R ?

Reported by barancev on 2013-02-12 07:34:01

  • Status changed: Accepted
  • Labels removed: Status-Untriaged

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

@barancev: I have signed it at the time of posting the patch (as Amitay Dobo).

Reported by amitayd on 2013-02-12 17:42:20

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

This issue was closed by revision 65ec3f4d1a92.

Reported by barancev on 2013-02-13 17:47:20

  • Status changed: Fixed

@lukeis
Copy link
Member Author

lukeis commented Mar 4, 2016

Reported by luke.semerau on 2015-09-17 18:16:26

  • Labels added: Restrict-AddIssueComment-Commit

@lukeis lukeis closed this as completed Mar 4, 2016
@SeleniumHQ SeleniumHQ locked and limited conversation to collaborators Mar 4, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant