org.openqa.selenium.NoSuchElementException: возвращаемый узел (null) не был элементом DOM при попытке найти карточное поле-iframe с помощью CssSelector - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь найти iframe по частичному идентификатору.Для этого метода я использовал: driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[id*='card-fields-number']"))); Я также пробовал xpath.

 driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(@id,'card-fields-number')]")));

Однако я все еще получаю это исключение:

org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element

Я обнаружил, что когда я включаю JavaScript для HtmlUnit, он может найти кадри переключитесь на него.Я бы предпочел не включать JavaScript, так как он работает очень медленно и добавляет ненужную задержку.

HTML-код iFrame:

<iframe class="card-fields-iframe" frameborder="0" id="card-fields-number-7pbvqg7azsf00000" name="card-fields-number-7pbvqg7azsf00000" scrolling="no" src="https://checkout.shopifycs.com/number?identifier=438599641d0ed8fe61c161d72e62b5f8&amp;location=https%3A%2F%2Fshopnicekicks.com%2F2192362%2Fcheckouts%2F438599641d0ed8fe61c161d72e62b5f8&amp;dir=ltr&amp;fonts[]=Lato" title="Field container for: Card number" style="height: 43px;"></iframe>

Идентификатор iFrame является динамическим, поэтому я прибегаю к использованию частичного идентификатора.

Ссылка на сайт: https://shopnicekicks.com/checkoutВы должны заполнить все, пока не дойдете до последней страницы, которая является страницей с информацией о кредитной карте.

Обновление iFrame находится внутри родительского фрейма.Родительская рамка:

<iframe srcdoc="<script>!function(){var e=function(e){var t={exports:{}};return e.call(t.exports,t,t.exports),t.exports},t=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,&quot;value&quot;in i&amp;&amp;(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&amp;&amp;e(t.prototype,n),i&amp;&amp;e(t,i),t}}(),n=function(e,t){if(!(e instanceof t))throw new TypeError(&quot;Cannot call a class as a function&quot;)},i=function(e){return e&amp;&amp;e.__esModule?e:{&quot;default&quot;:e}},o=e(function(e,i){&quot;use strict&quot;;Object.defineProperty(i,&quot;__esModule&quot;,{value:!0});var o=function(){function e(){var t=this;n(this,e),this.calls=[],window.ga=function(){for(var e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];return t.gaCall(n)}}return t(e,[{key:&quot;gaCall&quot;,value:function(e){var t=this;this.calls.push(e),clearTimeout(this.timeout),this.timeout=setTimeout(function(){t.calls.length>0&amp;&amp;t.sendMessage()},0)}},{key:&quot;listen&quot;,value:function(){var e=this;window.addEventListener(&quot;message&quot;,function(t){return e.receiveMessage(t)},!1)}},{key:&quot;sendMessage&quot;,value:function(){window.parent.postMessage({type:&quot;analytics&quot;,calls:this.calls},this.origin),this.calls=[]}},{key:&quot;receiveMessage&quot;,value:function(e){if(e.source===window.parent&amp;&amp;&quot;checkout_context&quot;===e.data.type){this.origin=e.origin,window.Shopify=e.data.Shopify,window.__st=e.data.__st;try{window.additionalScripts()}catch(e){console.error(&quot;User script error: &quot;,e)}}}}]),e}();i[&quot;default&quot;]=o});e(function(){&quot;use strict&quot;;var e=i(o);!function(){(new e[&quot;default&quot;]).listen()}()})}(&quot;undefined&quot;!=typeof global?global:&quot;undefined&quot;!=typeof window&amp;&amp;window); window.additionalScripts = function () {};</script>" src="https://checkout.shopify.com/2192362/sandbox/google_analytics_iframe" onload="this.setAttribute('data-loaded', true)" sandbox="allow-scripts" id="google-analytics-sandbox" tabindex="-1" class="visually-hidden" style="display:none" aria-hidden="true" data-loaded="true"></iframe>

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Поскольку у iframe есть тег iframe, вы можете переключиться на iframe, используя тэг, например:
driver.switchTo().frame(driver.findElement(By.tagName("iframe")));
И если вы хотите снова переключиться на содержимое по умолчанию, вы можете использовать driver.switchTo().defaultContent();

0 голосов
/ 10 февраля 2019

Это сообщение об ошибке ...

org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element

... означает, что такой элемент не найден, так как возвращаемый узел был null или не былэлемент DOM.

Это все еще открытая проблема с htmlunit-driver team.

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

  • Прежде всего, все современные браузеры имеют встроенную поддержку JavaScript.
  • HtmlUnitDriver - это WebDriver совместимый драйвер для HtmlUnit безголового браузера.Он имеет довольно хорошую поддержку JavaScript (которая постоянно совершенствуется) и способен работать даже с довольно сложными библиотеками AJAX, имитирующими Chrome , Firefox или Internet Explorer в зависимости от используемой конфигурации.Поэтому в идеале при работе с HtmlUnitDriver , JavaScript должен быть включен, иначе HtmlUnitDriver может не обнаруживать элементы на основе JavaScript .
  • Элемент выглядит как поле кредитной карты и исторически Номер кредитной карты и т. Д. Находится в пределах <iframes>.
  • Всякий раз, когда <iframe> находится в игреsrc атрибут тега <iframe> играет жизненно важную роль.
  • Согласно рекомендациям при переключении <iframe> вам нужнозаставить WebDriverWait для желаемого фрейма быть доступным и переключиться на него.

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

  • cssSelector :

    new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe.card-fields-iframe[id^='card-fields-number-'][src*='shopifycs']")));
    
  • xpath :

    new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[@class='card-fields-iframe' and starts-with(@id,'card-fields-number-')][contains(@src, 'shopifycs')]")));
    

Обновление

См. Снимок CssSelector, который идентифицирует совершенный элемент согласно предоставленному вами HTML:

CssSelector

0 голосов
/ 10 февраля 2019

Просто попробуйте с индексированием кадра "// iframe [index]", где index integer.

например, xpath: // iframe [1]

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

Пожалуйста, дайте мне знатьесли это решит проблему.

...