Не удается прочитать / получить доступ к динамически обновляемым данным в DOM Webdriver - PullRequest
0 голосов
/ 22 марта 2019

На странице есть таблица, заполненная информацией пользователя user1. Если щелкнуть узел, чтобы выбрать user2, данные таблицы динамически обновляются, и страница не перезагружается.

FindElement может найти элемент, но не может видеть новый текст в этом элементе

Использование явного или неявного ожидания не работает.

        do
            {
                driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
                vehicleTitle = driver.FindElement(By.XPath("//table[@id='vehicleRateSummary']/tbody/tr/th")).Text;
                driverTitle  = driver.FindElement(By.XPath("//table[@id='vehicleRateSummary']/tbody/tr[3]/th")).Text;
            }
            while (vehicleTitle == "");

HTML ...

<html debug="true" lang="en" xml:lang="en">
<head>
<body class="ui-layout-container" style="overflow: hidden; width: auto; height: auto; margin: 0px; position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px;">
<form name="form1" method="post" action="TransRateSummary.aspx" id="form1" onsubmit="return false;" novalidate="novalidate">
<div>
<script type="text/javascript">
<script src="/Production/WebResource.axd?d=pynGkmcFUV13He1Qd6_TZGbw1_qCDhf0FaNR4rXz3tF1n9KNi_pFKeZ4y9KlfWh_VnUER0IdmFID-JSZAPDbpA2&t=636776509224055265" type="text/javascript"/>
<script src="/Production/WebResource.axd?d=5GcSkSOyaAp9rgkHHDGLyws2fsmpXV5D9CKfy_myT9ytS0MLAqZ17ed-Ovveu2-B62tStCMGNKmroCqdqbMSvQ2&t=636776509224055265" type="text/javascript"/>
<script type="text/javascript">
<div>
<div id="revisionsContainer" class="ui-layout-center ui-layout-pane ui-layout-pane-center ui-layout-pane-hover ui-layout-pane-center-hover ui-layout-pane-open-hover ui-layout-pane-center-open-hover" style="position: absolute; margin: 0px; left: 406px; right: 0px; top: 0px; bottom: 0px; height: 909px; width: 1492px; z-index: 0; display: block; visibility: visible;">
<div id="revision0" class="revision" style="display: inline-block;">
<div id="vehicle1" class="vehicle" style="display: inline-block;">
<table id="vehicleRateSummary" class="summary">
<tbody>
<tr>
<th class="lj8ptbold" colspan="11">Vehicle 1 - Slot 1</th>
</tr>
<tr>
<tr>
<tr>
<tr>
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr>
<tr class="factorRow">
<tr class="factorRow">
<tr class="summaryRow">
<tr>
<tr class="factorRow">
<tr class="factorRow">
<tr>
<tr class="summaryRow">
<tr>
<tr class="summaryRow">
<tr>
<tr class="summaryRow">
<tr>
</tbody>
</table>
</div>
<div id="vehicle2" class="vehicle" style="display: none;">
<table id="vehicleRateSummary" class="summary">
<tbody>
<tr>
<th class="lj8ptbold" colspan="11">Vehicle 2 - Slot 2</th>
</tr>
<tr>
<tr>
<tr>
<td class="lj8pt" colspan="11">ERNIE STENSETH</td>
</tr>
<tr>
<tr class="factorRow">
<td class="lj8ptbold">Base Premium</td>
<td class="lj8pt italic"/>
<td class="rj8pt">31.990</td>
<td class="rj8pt">22.820</td>
<td class="rj8pt">4.000</td>
<td class="rj8pt">19.150</td>
<td class="rj8pt">12.430</td>
<td class="rj8pt">14.650</td>
<td class="rj8pt">50.670</td>
<td class="rj8pt">1.000</td>
<td class="rj8pt">1.000</td>
</tr>
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr class="factorRow">
<tr>
<tr class="factorRow">
<tr class="factorRow">
<tr class="summaryRow">
<tr>
<tr class="factorRow">
<tr class="factorRow">
<tr>
<tr class="summaryRow">
<tr>
<tr class="summaryRow">
<tr>
<tr class="summaryRow">
<tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="westPane" class="ui-layout-west no-padding no-margin ui-layout-container ui-layout-pane ui-layout-pane-west" style="overflow: hidden; position: absolute; margin: 0px; left: 0px; right: auto; top: 0px; bottom: 0px; height: 929px; z-index: 0; width: 398px; display: block; visibility: visible;">
<div id="revisionTreeContainer" class="ui-layout-center ui-layout-pane ui-layout-pane-center" style="position: absolute; margin: 0px; left: 0px; right: 0px; top: 0px; bottom: 356px; height: 551px; width: 376px; z-index: 0; display: block; visibility: visible;">
<div id="navBtns" class="navBtns ui-layout-south no-padding no-margin ui-layout-container ui-layout-pane ui-layout-pane-south" style="overflow: hidden; position: absolute; margin: 0px; top: auto; bottom: 0px; left: 0px; right: 0px; width: auto; z-index: 0; height: 348px; display: block; visibility: visible;">
<div id="" class="ui-layout-resizer ui-layout-resizer-south ui-draggable-handle ui-layout-resizer-open ui-layout-resizer-south-open" title="Resize" style="position: absolute; padding: 0px; margin: 0px; font-size: 1px; text-align: left; overflow: hidden; z-index: 2; cursor: s-resize; bottom: 350px; width: 398px; height: 6px; left: 0px;">
</div>
<input type="hidden" id="transId" name="transId" value=""/>
<input type="hidden" id="pn" name="pn" value=""/>
<script type="text/javascript">
<script type="text/javascript">
<input type="text" id="form_0_DisableAutoSubmit" value="" class="v_ignore" style="display: none;"/>
</form>
<div id="sumdiv" style="display: none;"/>
<span id="ModalBox_WaitDialog" style="display: none;">
<div id="ModalBox_MessageDialog" style="display: none;">
<div id="ModalBox_PromptDialog" style="display: none;">
<div id="" class="ui-layout-resizer ui-layout-resizer-west ui-draggable-handle ui-layout-resizer-open ui-layout-resizer-west-open" title="Resize" style="position: absolute; padding: 0px; margin: 0px; font-size: 1px; text-align: left; overflow: hidden; z-index: 2; cursor: w-resize; left: 400px; height: 931px; width: 6px; top: 0px;">
</body>
<script src="chrome-extension://ehemiojjcpldeipjhjkepfdaohajpbdo/googleChrome.js"/>
</html>

Выполнение этого просто застревает в этом цикле, так как текст элемента никогда не равен ничему, кроме "".

Ответы [ 3 ]

0 голосов
/ 22 марта 2019

Если вам нужно только проверить текст, то нет особой необходимости делать это специально для Selenium.Итак, вот решение, которое делает это через Jquery.

Обратите внимание, driver.Manage().Timeouts().ImplicitWait нужно устанавливать только один раз, если только вы не меняете значение на что-то другое.

Также обратите внимание, мойпример требует больше чем неявное ожидание между циклами.

            using OpenQA.Selenium.Support.Extensions;

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
            do
            {
                vehicleTitle = driver.ExecuteJavascript<string>("return $('#vehicleRateSummary > tbody > tr:nth-child(1) > th').text()");
                driverTitle  = driver.ExecuteJavascript<string>("return $('#vehicleRateSummary > tbody > tr:nth-child(3) > th').text()");
                System.Threading.Thread.Sleep(100); //Milliseconds
            }
            while (vehicleTitle == "");

Теперь я не могу гарантировать, что это работает без страницы, чтобы протестировать ее самостоятельно, но вы можете убедиться, что это работает, перейдя в консоль разработчика браузера,и вставив необработанный JQuery в нужное время, вы хотите извлечь текст $('#vehicleRateSummary > tbody > tr:nth-child(1) > th').text()

Теперь, если это не сработает, дайте мне знать.В частности, если ваша страница не использует JQuery, мы можем решить что-то еще.Если это не сработает, для нас может оказаться полезным увидеть html в таблице после того, как он обновится со значениями, которые вы ищете (таблица vehicleRateSummary).

Кроме того, важное примечание: th обычно является ячейкой строки заголовка таблицы.Принимая во внимание, что td обычно является ячейкой строки тела.Мы уверены, что это то, что мы должны искать здесь?Особый случай?Просто убедившись, что мы действительно ищем правильные элементы.

Теперь вот решение, которое можно использовать повсюду в вашем проекте, которое перепишет приведенный выше код (если вам это нравится):

    //Goes in some static tools class. Must be a static class.
    private static void WaitUntil(this IWebDriver driver, Func<bool> Condition, float timeout)
    {

        float timer = timeout;
        while (!Condition.Invoke() && timer > 0f)
        {

            System.Threading.Thread.Sleep(500);
            timer -= 0.5f;

        }
        System.Threading.Thread.Sleep(500);

    }

     //And your new code 
     driver.WaitUntil(() => driver.ExecuteJavascript<bool>("return $('#vehicleRateSummary > tbody > tr:nth-child(1) > th').text().length > 0"));
     driver.WaitUntil(() => driver.ExecuteJavascript<bool>("return $('#vehicleRateSummary > tbody > tr:nth-child(3) > th').text().length > 0"));
0 голосов
/ 24 марта 2019

Я ценю помощь.

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

0 голосов
/ 22 марта 2019

Подождите, пока элемент будет виден, а затем получите текст:

var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
vehicleTitle = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//table[@id='vehicleRateSummary']/tbody/tr/th"))).Text;
driverTitle = driver.FindElement(By.XPath("//table[@id='vehicleRateSummary']/tbody/tr[3]/th")).Text;

Попробуйте с textContent:

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
do
{
    Thread.Sleep(1000);
    vehicleTitle = (string)js.ExecuteScript("return arguments[0].textContent", driver.FindElement(By.XPath("//table[@id='vehicleRateSummary']/tbody/tr/th")));
}
while (vehicleTitle == "");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...