0

我有一个使用 Thycidides/jbehave 的测试套件,它运行良好(尽管针对旧版本的 FireFox,因为开发切换到 Sernity BDD)。我现在已经迁移到新的 Serenity BDD(仍然是 jbehave)并更新了 FireFox,但是在尝试切换到特定页面/测试上的框架时突然遇到错误。

我们的网站有很多框架,但框架切换适用于所有页面/测试,期望在单个页面/测试上(这似乎与其他工作测试具有相同的框架结构)。当我尝试切换到特定框架(我知道它在那里)时,我得到一个“元素属于与当前框架不同的框架 - 切换到其包含的框架以使用它”(以及指向 stale_element_reference 的链接)(SerenityManagedException. detachedCopyOf) 这没有多大意义,这就是我想要做的。我编写了一些贯穿所有帧的替代代码,以确保我切换到的帧存在并且确实存在。

“基本”框架结构:

<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>

我正在尝试切换到“主”框架,所以我首先切换到默认内容,然后尝试切换到“主”

getDriver().switchTo().defaultContent();

String SAML = System.getProperty("login.user.saml").toString();
if(SAML.equalsIgnoreCase("false")) // some sites have a 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("正在切换到'主'框架..."); 是最后一个执行的,所以它在 getDriver().switchTo().frame("main");

下面的代码找到了“main”,这意味着它应该存在于活动框架中并且也可以切换,因为 findElements 只从活动框架 afaik 返回:

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);
            }

        }

有没有人有解决此错误的想法或解决方法?无法发布完整的 html 网站,因为它们包含敏感数据/代码。

4

1 回答 1

0

我找到了解决方法

经过大量的试验和错误,我发现了以下问题和解决方法:

  1. 帧切换异常实际上是一个 StaleElementReferenceException,因此错误消息“元素属于与当前帧不同的帧 - 切换到其包含的帧以使用它”具有误导性。

  2. 如果我忽略异常而不是破坏,我可以按照我的意愿访问框架内的元素。因此,无论异常如何,它似乎都切换到了“主”框架

  3. 忽略异常后,尝试将密钥发送到框架内的元素时出现新错误。例外是'Permission denied to access property "__raven__"' 从我可以谷歌来看,这个例外似乎与 jQuery 有关,但我在 serenity.properties 中有 serenity.jquery.integration=false。

  4. 再一次,我可以通过忽略异常来继续测试,并且所需的 sendKeys 值仍然输入到导致异常的字段中。

  5. 跳过第一个__raven__错误后,我稍后会得到另一个错误(在两个错误之间是不会导致异常的 sendKey/findElement 使用),当我使用 findElements 时,我也可以通过忽略错误来解决。

有谁知道为什么会发生这两个异常?

虽然测试现在可以工作,但它是一种非常肮脏的方式,所以如果可能的话,仍然希望问题得到解决。

“工作”帧切换的新代码:

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;
于 2016-05-27T12:29:32.737 回答