0

私は Thycidides/jbehave を使用していたテスト スイートを持っていて、正常に動作しました (ただし、開発が Sernity BDD に切り替えられたため、古いバージョンの FireFox に対して)。新しい Serenity BDD (まだ jbehave) に移行し、FireFox を更新しましたが、特定のページ/テストでフレームに切り替えようとすると、突然エラーが発生します。

私たちのサイトには多くのフレームがありますが、フレームの切り替えはすべてのページ/テストで機能し、単一のページ/テストを除きます (他の動作中のテストと同じフレーム構造を持っているようです)。特定のフレーム (そこにあることがわかっている) に切り替えようとすると、「要素は現在のフレームとは異なるフレームに属しています - そのフレームを含むフレームに切り替えて使用します」(および stale_element_reference へのリンク) (SerenityManagedException.これはあまり意味がありません。それが私がやろうとしていることです。切り替え先のフレームが存在することを確認するために、すべてのフレームを実行する代替コードをいくつか書きました。

「基本」フレーム構造:

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

「メイン」フレームに切り替えようとしているので、最初に defaultcontent に切り替えてから「メイン」に切り替えようとします

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"); で失敗します。

以下のコードは、「メイン」を見つけます。これは、アクティブ フレームに存在し、切り替え可能であることを意味します。これは、findElements がアクティブ フレームからのみ返されるためです。

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__"' 、Google で調べたところ、この例外は jQuery に関連しているようですが、serenity.properties に serenity.jquery.integration=false があります。

  4. ここでも、例外を無視してテストを続行できますが、必要な sendKeys 値は、例外の原因となったフィールドに入力されたままです。

  5. 最初のエラーをスキップした後、__raven__エラーを無視して回避できるfindElementsを使用すると、後で別のエラーが発生します(2つのエラーの間には、例外を引き起こさないsendKey/findElementの使用があります)。

これら2つの例外が発生する理由を誰か知っていますか?

テストは機能するようになりましたが、かなり汚い方法なので、可能であれば問題を解決したいと考えています。

「動作中」のフレーム スイッチの新しいコード:

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 に答える