Как обеспечить загрузку всех полей на странице в селене, чтобы ни одно из них не устарело?

Проблема

У меня есть страница PeopleSoft, которую я пытаюсь протестировать с помощью веб-драйвера Selenium для Java. Однако я продолжаю сталкиваться с этой ошибкой:

org.openqa.selenium.StaleElementReferenceException: ссылка на устаревший элемент: элемент не прикреплен к документу страницы

Я прочитал здесь, < href="https://stackoverflow.com/questions/8541110/check-for-a-stale-element-using-selenium-2">здесь и здесь, а также другие вопросы о переполнении стека, и ни один из ответов не работает для меня.

Макет страницы

Страница PeopleSoft, которую я тестирую, представляет собой форму I9, и часть, которая меня интересует, выглядит так: Страница I9

Соответствующий HTML-код действительно большой и беспорядочный, как и все страницы PeopleSoft, и в его середине есть iframe, который охватывает почти всю всю страницу.

Для справки, этот JSFiddle содержит весь HTML-код, который находится внутри этого iframe.

Вот часть, которая соответствует разделам на изображении выше:

<table role='presentation' border='0' id='ACE_width' cellpadding='0' cellspacing='0' class='PSPAGECONTAINER' cols='46' width='963'>
  <!-- OMITTED -->

  <tr>
    <td height='16'></td>
    <td colspan='19' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_LAST_NAMElbl'>
        <label for='G_FORM_I9_G_LAST_NAME' id='G_FORM_I9_G_LAST_NAME_LBL' class='PSEDITBOXLABEL'>*Last Name (Family Name)</label>
      </DIV>
    </td>
    <td colspan='9' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_FIRST_NAMElbl'>
        <label for='G_FORM_I9_G_FIRST_NAME' id='G_FORM_I9_G_FIRST_NAME_LBL' class='PSEDITBOXLABEL'>*First Name (Given Name)</label>
      </DIV>
    </td>
    <td colspan='3' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_MIDDLE_INITIALlbl'>
        <label for='G_FORM_I9_G_MIDDLE_INITIAL' id='G_FORM_I9_G_MIDDLE_INITIAL_LBL' class='PSEDITBOXLABEL'>Middle Initial</label>
      </DIV>
    </td>
    <td colspan='14' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_MAIDEN_NAMElbl'>
        <label for='G_FORM_I9_G_MAIDEN_NAME' id='G_FORM_I9_G_MAIDEN_NAME_LBL' class='PSEDITBOXLABEL'>Other Last Names Used (if any)</label>
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='32' colspan='2'></td>
    <td colspan='19' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_LAST_NAME'>
        <input type='text' name='G_FORM_I9_G_LAST_NAME' id='G_FORM_I9_G_LAST_NAME' tabindex='43' value="Tiger" class='PSEDITBOX' style='width:232px; ' maxlength='30' onchange="addchg_win0(this);oChange_win0=this;" aria-required='true' />
      </DIV>
    </td>
    <td colspan='9' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_FIRST_NAME'>
        <input type='text' name='G_FORM_I9_G_FIRST_NAME' id='G_FORM_I9_G_FIRST_NAME' tabindex='44' value="Tony" class='PSEDITBOX' style='width:160px; ' maxlength='30' onchange="addchg_win0(this);oChange_win0=this;" aria-required='true' />
      </DIV>
    </td>
    <td colspan='2' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_MIDDLE_INITIAL'>
        <input type='text' name='G_FORM_I9_G_MIDDLE_INITIAL' id='G_FORM_I9_G_MIDDLE_INITIAL' tabindex='45' value="" class='PSEDITBOX' style='width:19px; ' maxlength='1' onchange="addchg_win0(this);return doEdits_win0(this,'','N','N','N','N','Y','N',0);"
        />
      </DIV>
    </td>
    <td colspan='14' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_MAIDEN_NAME'>
        <input type='text' name='G_FORM_I9_G_MAIDEN_NAME' id='G_FORM_I9_G_MAIDEN_NAME' tabindex='46' value="" class='PSEDITBOX' style='width:180px; ' maxlength='50' />
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='16'></td>
    <td colspan='21' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_ADDRESSlbl'>
        <label for='G_FORM_I9_G_ADDRESS' id='G_FORM_I9_G_ADDRESS_LBL' class='PSEDITBOXLABEL'>*Address (Street Number and Name)</label>
      </DIV>
    </td>
    <td colspan='5' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_APARTMENT_NBRlbl'>
        <label for='G_FORM_I9_G_APARTMENT_NBR' id='G_FORM_I9_G_APARTMENT_NBR_LBL' class='PSEDITBOXLABEL'>Apt. Number</label>
      </DIV>
    </td>
    <td colspan='7' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_CITYlbl'>
        <label for='G_FORM_I9_G_CITY' id='G_FORM_I9_G_CITY_LBL' class='PSEDITBOXLABEL'>*City or Town</label>
      </DIV>
    </td>
    <td colspan='6' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_STATElbl'>
        <label for='G_FORM_I9_G_STATE' id='G_FORM_I9_G_STATE_LBL' class='PSEDITBOXLABEL'>*State</label>
      </DIV>
    </td>
    <td colspan='6' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_POSTALlbl'>
        <label for='G_FORM_I9_G_POSTAL' id='G_FORM_I9_G_POSTAL_LBL' class='PSEDITBOXLABEL'>*Zip Code</label>
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='32' colspan='2'></td>
    <td colspan='20' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_ADDRESS'>
        <input type='text' name='G_FORM_I9_G_ADDRESS' id='G_FORM_I9_G_ADDRESS' tabindex='47' value="" class='PSEDITBOX' style='width:324px; ' maxlength='50' aria-required='true' />
      </DIV>
    </td>
    <td colspan='6' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_APARTMENT_NBR'>
        <input type='text' name='G_FORM_I9_G_APARTMENT_NBR' id='G_FORM_I9_G_APARTMENT_NBR' tabindex='48' value="" class='PSEDITBOX' style='width:81px; ' maxlength='10' />
      </DIV>
    </td>
    <td colspan='8' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_CITY'>
        <input type='text' name='G_FORM_I9_G_CITY' id='G_FORM_I9_G_CITY' tabindex='49' value="" class='PSEDITBOX' style='width:120px; ' maxlength='30' aria-required='true' />
      </DIV>
    </td>
    <td colspan='5' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_STATE'>
        <input type='text' name='G_FORM_I9_G_STATE' id='G_FORM_I9_G_STATE' tabindex='50' value="" class='PSEDITBOX' style='width:53px; ' maxlength='6' onchange="addchg_win0(this);oChange_win0=this;" aria-required='true' />
        <a class='PSHYPERLINK' name='G_FORM_I9_G_STATE$prompt' id='G_FORM_I9_G_STATE$prompt' tabindex='51' href="javascript:pAction_win0(document.win0,'G_FORM_I9_G_STATE$prompt');">
          <img src="/cs/ps/cache2/PT_PROMPT_LOOKUP_1.gif" alt='Look up State (Alt+5)' title='Look up State (Alt+5)' border='0' align='absmiddle' />
        </a>
      </DIV>
    </td>
    <td colspan='5' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_POSTAL'>
        <input type='text' name='G_FORM_I9_G_POSTAL' id='G_FORM_I9_G_POSTAL' tabindex='52' value="" class='PSEDITBOX' style='width:80px; ' maxlength='12' onchange="addchg_win0(this);oChange_win0=this;" aria-required='true' />
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='16'></td>
    <td colspan='9' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_BIRTHDATElbl'>
        <label for='G_FORM_I9_G_BIRTHDATE' id='G_FORM_I9_G_BIRTHDATE_LBL' class='PSEDITBOXLABEL'>*Date of Birth (mm/dd/yyyy)</label>
      </DIV>
    </td>
    <td colspan='13' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_SSNlbl'>
        <label for='G_FORM_I9_G_SSN' id='G_FORM_I9_G_SSN_LBL' class='PSEDITBOXLABEL'>*U.S. Social Security Number</label>
      </DIV>
    </td>
    <td colspan='14' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_EMAILIDlbl'>
        <label for='G_FORM_I9_G_EMAILID' id='G_FORM_I9_G_EMAILID_LBL' class='PSEDITBOXLABEL'>Employee&#039;s E-mail Address</label>
      </DIV>
    </td>
    <td colspan='9' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_PHONElbl'>
        <label for='G_FORM_I9_G_PHONE' id='G_FORM_I9_G_PHONE_LBL' class='PSEDITBOXLABEL'>Employee&#039;s Telephone Number</label>
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='9' colspan='2'></td>
    <td colspan='9' rowspan='2' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_BIRTHDATE'>
        <input type='text' name='G_FORM_I9_G_BIRTHDATE' id='G_FORM_I9_G_BIRTHDATE' tabindex='53' value="05/05/1955" class='PSEDITBOX' style='width:71px; ' maxlength='10' onchange="addchg_win0(this);return doEdits_win0(this,'DMDY/450','N','N','N','N','N','N',0);"
        onkeyup="if (isPromptKey(event))DatePrompt_win0('G_FORM_I9_G_BIRTHDATE','G_FORM_I9_G_BIRTHDATE','450',false);return false;" aria-required='true' />
        <a class='PSHYPERLINK' name='G_FORM_I9_G_BIRTHDATE$prompt' id='G_FORM_I9_G_BIRTHDATE$prompt' tabindex='54' onfocus='doFocus_win0(this,true,false);' href="javascript:DatePrompt_win0('G_FORM_I9_G_BIRTHDATE','G_FORM_I9_G_BIRTHDATE$prompt','450',false);">
          <img src="/cs/ps/cache2/PT_CALENDAR_1.gif" alt='Choose a date (Alt+5)' title='Choose a date (Alt+5)' border='0' align='absmiddle' />
        </a>
      </DIV>
    </td>
    <td colspan='6' rowspan='2' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_SSN'>
        <input type='password' name='G_FORM_I9_G_SSN' id='G_FORM_I9_G_SSN' tabindex='55' value="888881125" class='PSEDITBOX' style='width:74px; ' maxlength='9' onchange="addchg_win0(this);oChange_win0=this;" aria-required='true' />
      </DIV>
    </td>
    <td colspan='6'></td>
    <td colspan='16' rowspan='2' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_EMAILID'>
        <input type='text' name='G_FORM_I9_G_EMAILID' id='G_FORM_I9_G_EMAILID' tabindex='58' value="" class='PSEDITBOX' style='width:232px; ' maxlength='60' />
      </DIV>
    </td>
    <td colspan='7' rowspan='2' nowrap='nowrap' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_G_PHONE'>
        <input type='text' name='G_FORM_I9_G_PHONE' id='G_FORM_I9_G_PHONE' tabindex='59' value="" class='PSEDITBOX' style='width:179px; ' maxlength='24' onchange="addchg_win0(this);oChange_win0=this;" />
      </DIV>
    </td>
  </tr>
  <tr>
    <td height='23' colspan='2'></td>
    <td colspan='6' valign='top' align='left'>
      <DIV id='win0divG_FORM_I9_DRV_G_SSN'><span id='G_FORM_I9_DRV_G_SSN$span' onMouseOver="MOpopupObj_win0.StartPopup('win0divG_FORM_I9_DRV_G_SSN', 'G_FORM_I9_DRV_G_SSN_G_POPUP_SSN', 406, 90);" onMouseOut="MOpopupObj_win0.StopPopup(); " class='PSHYPERLINK' style='border-bottom:1px dashed black;padding-bottom:1px;display:inline-block;'><a name='G_FORM_I9_DRV_G_SSN' id='G_FORM_I9_DRV_G_SSN'  ptlinktgt='pt_peoplecode' tabindex='56' onclick='javascript:cancelBubble(event);' href="javascript:submitAction_win0(document.win0,'G_FORM_I9_DRV_G_SSN');"  class='PSHYPERLINK' >View</a></span>
      </DIV>
      <div id="G_FORM_I9_DRV_G_SSN_G_POPUP_SSN" style="visibility:hidden; position:absolute; top:0; left:0;">
        <DIV class='ps_pspagecontainer' id='win0divPSPAGECONTAINER_G_POPUP_SSN'>
          <table role='presentation' border='0' id='ACE_width' cellpadding='0' cellspacing='0' class='PSPAGECONTAINER' cols='2' width='379'>
            <tr>
              <td width='16' height='8'></td>
              <td width='363'></td>
            </tr>
            <tr>
              <td height='56'></td>
              <td valign='top' align='left'>
                <DIV id='win0divG_FORM_I9_'>
                  <table role='presentation' border='0' id='ACE_G_FORM_I9_' cellpadding='0' cellspacing='0' cols='3' width='363' class='PAGROUPBOXLABELINVISIBLE' style='border-style:none'>
                    <tr>
                      <td width='36' height='10'></td>
                      <td width='121'></td>
                      <td width='206'></td>
                    </tr>
                    <tr>
                      <td height='1'></td>
                      <td rowspan='2' valign='top' align='left'>
                        <DIV id='win0divG_FORM_I9_G_SSN$9$lbl'><span class='PSEDITBOXLABEL'>Social Security #</span> 
                        </DIV>
                      </td>
                    </tr>
                    <tr>
                      <td height='27'></td>
                      <td valign='top' align='left'>
                        <DIV id='win0divG_FORM_I9_G_SSN$9$'><span class='PSEDITBOX_DISPONLY' id='G_FORM_I9_G_SSN$9$'>888881125</span>
                        </DIV>
                      </td>
                    </tr>
                  </table>
                </DIV>
              </td>
            </tr>
            <tr>
              <td height='8' colspan='2'></td>
            </tr>
          </table>
        </DIV>
      </DIV>
    </td>
  </tr>

  <!-- OMITTED -->

</table>

Запуск кода Selenium

Теперь я пытаюсь ввести данные в эту форму, но продолжаю получать указанное выше исключение. Когда я захожу на эту страницу, я сначала прохожу через страницу SSO для аутентификации. Затем он перенаправляет меня на форму. Там нет проблем. Это мой код для этого (обратите внимание, что data — это POJO с данными, а driver — это ChromeWebDriver).

driver.switchTo().frame("TargetContent");

driver.findElement(By.id("G_FORM_I9_G_LAST_NAME")).clear();
driver.findElement(By.id("G_FORM_I9_G_LAST_NAME")).sendKeys(data.lastName, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_FIRST_NAME")).clear();
driver.findElement(By.id("G_FORM_I9_G_FIRST_NAME")).sendKeys(data.firstName, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_ADDRESS")).clear();
driver.findElement(By.id("G_FORM_I9_G_ADDRESS")).sendKeys(data.address, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_CITY")).clear();
driver.findElement(By.id("G_FORM_I9_G_CITY")).sendKeys(data.city, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_STATE")).clear();
driver.findElement(By.id("G_FORM_I9_G_STATE")).sendKeys(data.state, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_POSTAL")).clear();
driver.findElement(By.id("G_FORM_I9_G_POSTAL")).sendKeys(data.postal, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_EMAILID")).clear();
driver.findElement(By.id("G_FORM_I9_G_EMAILID")).sendKeys(data.email, Keys.TAB);
driver.findElement(By.id("G_FORM_I9_G_CITIZEN_CHK")).click();
driver.findElement(By.id("G_FORM_I9_DRV_G_EE_SIGNATURE_PB")).click();

Я получаю ошибку в различных точках на протяжении всего процесса. Иногда он терпит неудачу в первом поле, в которое пытается поместить текст, иногда во втором, а иногда и в более позднем поле.

Попытки решения

Чтобы решить эту проблему, я попытался вызвать этот метод:

private void waitForLoad(WebDriver driver)
{
    new WebDriverWait(driver, 30)
            .until((ExpectedCondition<Boolean>) wd -> ((JavascriptExecutor) wd)
                    .executeScript("return document.readyState").equals("complete"));
}

Я также пробовал это:

new WebDriverWait(driver, 5).until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//*[starts-with(@id, \"G_FORM_I9_\")]")));

Что мне не хватает? Что еще мне нужно проверить, чтобы убедиться, что поля действительно доступны? Я много раз пытался отладить это в IntelliJ, но подозреваю, что действие остановки в точке останова загружает страницу, поэтому я никогда не вижу ошибки, потому что ни один элемент не устарел.


person Cache Staheli    schedule 05.01.2017    source источник


Ответы (1)


Похоже, что иногда вызов clear() изменяет ссылку на ваш элемент, и пока страница обновляется, вы пытаетесь снова найти этот элемент и найти старую ссылку, что вызывает StaleElementReferenceException при sendKeys().

Если вы уже знаете поля, с которыми у вас возникает проблема, вы можете попробовать следующее:

WebDriverWait wait = new WebDriverWait (driver, 30);
WebElement element = driver.findElement(By.id("G_FORM_I9_G_LAST_NAME"));
element.clear();
wait.until(ExpectedConditions.stalenessOf(element));
driver.findElement(By.id("G_FORM_I9_G_LAST_NAME")).sendKeys(data.lastName, Keys.TAB);

Но если вы не знаете, какие поля вызывают проблему, и элемент не устареет, вы получите ошибку TimeoutException.

person Renato    schedule 06.01.2017
comment
Похоже проблема действительно в этом. Очень интересно. - person Cache Staheli; 06.01.2017