Frame issues after migrating to Serenity BDD jBehave

265 views
Skip to first unread message

Martin Aas Andersen

unread,
May 26, 2016, 7:29:45 AM5/26/16
to Serenity BDD Users Group
Hi

I had a working testsuite running on Thucydides jBehave xxx (although gainst a older version of FireFox).
After I migrated to Serenity BDD jBehave and updated FireFox I'm getting a weird frame error I can't seem to solve.

Our website (that's tested against) have a LOT of frames and a certain frame switch seems to be working for all pages/test except a single test/page (even though the page seems to have the same frame structure as the working ones) where I get an "Element belongs to a different frame than the current one - switch to its containing frame to use it".
The error seems strange as it only happens with one specific frame, so I can switch to other frames (like 'kalender') on the same level without problems.

Out basic frame layout is this:
<html>
    <head>     
    </head>
    <frameset cols="5,*" border="0" frameborder="no" framespacing="0">
        <frameset rows="145,*" border="0" frameborder="no" framespacing="0">
            <frame name="kalender" src="../calendar/Month.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
            <frame name="dagskalender" src="../calendar/NewTimeReg.jsp" marginwidth="10" marginheight="20" noresize="" scrolling="no">
        </frameset>
        <frameset rows="50,*,1" border="0" frameborder="NO" framespacing="0">
            <frameset cols="63,175,*,35" border="0" frameborder="NO" framespacing="0">
                <frame name="dagbund" src="Mail.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="NO">
                <frame name="soeg" src="../search/main/Cont.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
                <frame name="topbar" src="TopBarMid.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
                <frame name="topbarende" src="TopBarRight.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
            </frameset>
            <frame name="main" src="../startpage/Fram.jsp?null" marginwidth="0" marginheight="0" noresize="">
            <frameset cols="33%,33%,33%,*" border="0" frameborder="NO" framespacing="0">
                <frame name="skjult" src="Blank.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
                <frame name="skjult2" src="Blank2.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
                <frame name="skjult3" src="Blank3.jsp" marginwidth="0" marginheight="0" noresize="" scrolling="no">
                <frame name="AppletLoader" src="" marginwidth="0" marginheight="0" noresize="" scrolling="no">
            </frameset>  
        </frameset>
    </frameset>
</html>

I'm trying to execute this:
getDriver().switchTo().defaultContent();
 
String SAML = System.getProperty("login.user.saml").toString();
if(SAML.equalsIgnoreCase("false")) // some sites have an extra parent frame
{
    staticlogger.info( "Switching to 'system' frame..." ); 
    getDriver().switchTo().frame("system"); //disable step if SAML-login
}      
staticlogger.info( "Switching to 'main' frame..." );
getDriver().switchTo().frame("main");  
staticlogger.info( "Done switching to 'main' frame..." ); 
 
It error triggers when  getDriver().switchTo().frame("main");   is executed. I did a alternative switch code where I run all frames through and it finds the 'main' frame but still causes error when trying to switchTo it.

List<WebElement> ele = getDriver().findElements(By.tagName("frame"));

        for(WebElement el : ele)

        {

            staticlogger.info( "Frame: " + el.getAttribute("name") + " ID: " + el.getAttribute("id"));

            if(el.getAttribute("name").equalsIgnoreCase("main"))

            {

                staticlogger.info( "Switching to 'main' frame..." );   

                getDriver().switchTo().frame(el);

            }

 

        }

Shouldn't findElements only return elements from the active frame? Meaning when it finds the 'main' frame it should be switchable to. 

The stacktrace I get is:
net.serenitybdd.core.exceptions.SerenityManagedException: Element belongs to a different frame than the current one - switch to its containing frame to use it
Command duration or timeout: 15.11 seconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.53.0', revision: '35ae25b1534ae328c771e0856c93e187490ca824', time: '2016-03-15 10:43:46'
System info: host: 'xx', ip: '10.xxx.xxx.xx', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-229.1.2.el7.x86_64', java.version: '1.8.0_66'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=46.0.1, platform=LINUX, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: bc102c91-ffac-41a4-aa1f-633067acddfb
 at net.serenitybdd.core.exceptions.SerenityManagedException.detachedCopyOf(SerenityManagedException.java:20)
 at net.thucydides.core.steps.StepInterceptor.reportMethodError(StepInterceptor.java:281)
 at net.thucydides.core.steps.NormalMethodRunner.invokeMethodAndNotifyFailures(NormalMethodRunner.java:22)
 at net.thucydides.core.steps.StepInterceptor.runNormalMethod(StepInterceptor.java:269)
 at net.thucydides.core.steps.StepInterceptor.testStepResult(StepInterceptor.java:127)
 at net.thucydides.core.steps.StepInterceptor.intercept(StepInterceptor.java:61)
 at org.TeamOnline.jbehave.steps.ResponseTimesUserSteps$$EnhancerByCGLIB$$2b7019e.chooses_last_3_days(<generated>)
 at org.TeamOnline.jbehave.definitions.ResponseTimesDefinitionSteps.givenTheUserFiltersFor3DaysAndTitle(ResponseTimesDefinitionSteps.java:83)
 (reflection-invoke)
 at org.jbehave.core.steps.StepCreator$ParametrisedStep.perform(StepCreator.java:599)
 at org.jbehave.core.embedder.PerformableTree$FineSoFar.run(PerformableTree.java:340)
Does anyone have any idea what could be causing the error or any way to work around it? I need to access some elements within the frame.

Regards
Martin 
 

Martin Aas Andersen

unread,
May 27, 2016, 8:26:53 AM5/27/16
to Serenity BDD Users Group
After a lot of trial and error I found the following issues and workarounds:
 
1. The frame switch exception is actually a StaleElementReferenceException, so the error message "Element belongs to a different frame than the current one - switch to its containing frame to use it" is misleading imo.
2. If I ignore the exception instead of breaking I can access elements within the frame as I wanted to. So seems it switched to the 'main' frame regardless of the exception
3. After ignoring the exception I got a new error when trying to sendKeys to a element within the frame. The exception is 'Permission denied to access property "__raven__"'
From what I could Google it seems this exception can be related to jQuery but I have serenity.jquery.integration=false in serenity.properties.
4. Once again I could continue the test by ignoring the exception and the desired sendKeys value is still entered into the field that caused the exception.
5. After skipping the first __raven__ error I get another later on (in between the 2 errors are sendKey/findElement usage that does not cause exception) when using findElements which I also can workaround by ignoring error.
 
Does anyone have any idea why these 2 exceptions occur and is any of this an actual bug in the framework?
Although the test works now it's a pretty dirty way of doing it, so would still like the issues solved if possible.
 
New code for "working" frame switch:
 

  String SAML = System.getProperty("login.user.saml").toString();

  getDriver().switchTo().defaultContent();
  if(SAML.equalsIgnoreCase("false"))

  {
   staticlogger.info( "Switching to 'system' frame..." ); 
   getDriver().switchTo().frame("system"); //disable step if SAML-login
  }  
  staticlogger.info( "Switching to 'main' frame..." );

  getDriver().manage().timeouts().implicitlyWait( 2, TimeUnit.SECONDS );
  try
  {
   getDriver().switchTo().frame("main"); 
  }
  catch ( StaleElementReferenceException ser )
  {      
     staticlogger.info( "WARNING: Stale 'main' frame");     
  }
  catch ( NoSuchFrameException nsf )
  {      
     staticlogger.info( "ERROR: No 'main' frame found");            
    
  } catch ( Exception e )
  {
      staticlogger.info( "ERROR: " + e.getMessage() );
  }
  getDriver().manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );

  staticlogger.info( "Done switching to 'main' frame..." );

Workaround for __raven__
    long startTime = System.currentTimeMillis();
    driver.manage().timeouts().implicitlyWait( 250, TimeUnit.MILLISECONDS );
    WebElement we = null;
    boolean unfound = true;
    int tries = 0;
    while ( unfound && tries < 8 ) {
      tries += 1;
      try {
        we = driver.findElement( locator );
        unfound = false; // FOUND IT
      } catch ( StaleElementReferenceException ser ) {      
        staticlogger.info( "Try [" + tries + "] - ERROR: Stale element. " + locator.toString() );
        unfound = true;
      } catch ( NoSuchElementException nse ) {      
        staticlogger.info( "Try [" + tries + "] - ERROR: No such element. " + locator.toString() );
        unfound = true;
      } catch ( Exception e ) {
        staticlogger.info( "Try [" + tries + "] - " + e.getMessage() );
      }
    }
    long endTime = System.currentTimeMillis();
    long totalTime = endTime - startTime;
    if (we != null)  
     staticlogger.info("Try [" + tries + "] - Found element after " + totalTime + " milliseconds.");
    else   
     staticlogger.info("Element NOT found after looking for " + totalTime + " milliseconds.");    
    driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );
    return we;

    

Martin Aas Andersen

unread,
Sep 1, 2016, 8:44:32 AM9/1/16
to Serenity BDD Users Group
Turns out the issues where caused by a error in FireFox because we have Sentry running (where raven.js belongs as it turns out)
I solved it for now by switching to Chrome. Another suggestion i got where to add try/catch to wrap in raven.js
Reply all
Reply to author
Forward
0 new messages