Исключение не взаимодействующее с элементом в Selen Automation

В приведенном ниже коде я не могу отправить ключи пароля в поле пароля, я попытался щелкнуть поле, очистить поле и отправить ключи. Но сейчас работаю по любому методу. Но это работает, если я отлаживаю и тестирую

  public class TestMail {
   protected static WebDriver driver;

   protected static String result;

   @BeforeClass

   public static void setup()  {
              System.setProperty("webdriver.gecko.driver","D:\\geckodriver.exe");

   driver = new FirefoxDriver();

   driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

  }

   @Test

 void Testcase1() {

   driver.get("http://mail.google.com");

   WebElement loginfield = driver.findElement(By.name("Email"));
   if(loginfield.isDisplayed()){
       loginfield.sendKeys("ragesh@gmail.in");
   }
   else{
  WebElement newloginfield = driver.findElemnt(By.cssSelector("#identifierId"));                                      
       newloginfield.sendKeys("ragesh@gmail.in");
      // System.out.println("This is new login");
   }


    driver.findElement(By.name("signIn")).click();

  // driver.findElement(By.cssSelector(".RveJvd")).click();

   driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
 // WebElement pwd = driver.findElement(By.name("Passwd"));
  WebElement pwd = driver.findElement(By.cssSelector("#Passwd"));

  pwd.click();
  pwd.clear();
 // pwd.sendKeys("123");
 if(pwd.isEnabled()){
     pwd.sendKeys("123");
 }
 else{
     System.out.println("Not Enabled");
 }

13 ответов

Решение

Попробуйте установить неявное ожидание, возможно, 10 секунд.

gmail.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Или установите явное ожидание. Явное ожидание - это код, который вы определили для ожидания определенного условия, прежде чем продолжить работу в коде. В вашем случае это видимость поля ввода пароля. (Благодаря комментарию ainlolcat)

WebDriver gmail= new ChromeDriver();
gmail.get("https://www.gmail.co.in"); 
gmail.findElement(By.id("Email")).sendKeys("abcd");
gmail.findElement(By.id("next")).click();
WebDriverWait wait = new WebDriverWait(gmail, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("Passwd")));
gmail.findElement(By.id("Passwd")).sendKeys("xyz");

Объяснение: Причина, по которой selenium не может найти элемент, заключается в том, что идентификатор поля ввода пароля изначально скрыт Passwd. После того, как вы нажмете кнопку "Далее", Google сначала проверит введенный адрес электронной почты, а затем отобразит поле ввода пароля (изменив идентификатор с Passwd-hidden на Passwd). Таким образом, когда поле пароля все еще скрыто (т. Е. Google все еще проверяет идентификатор электронной почты), ваш веб-драйвер начинает поиск поля ввода пароля с идентификатором Passwd, который все еще скрыт. И, следовательно, исключение выдается.

Ошибка "элемент не взаимодействует" может означать две вещи:

а. Элемент не отрисован должным образом:

Решение для этого - просто использовать неявное / явное ожидание

  • Неявное ожидание:

    driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);

  • Явное ожидание:

    WebDriverWait wait = новый WebDriverWait (драйвер, 20); element1 = wait.until (ExpectedConditions.elementToBeClickable (By.className ("fa-stack-1x")));

б. Элемент отрисован, но его нет в видимой части экрана:

Решение - просто прокрутить до элемента. В зависимости от версии Selenium с этим можно справиться по-разному, но я предоставлю решение, которое работает во всех версиях:

          JavascriptExecutor executor = (JavascriptExecutor) driver;
    executor.executeScript("arguments[0].scrollIntoView(true);", element1);
  1. Предположим, все это не удается, тогда другой способ - снова использовать исполнителя Javascript следующим образом:

    executeor.executeScript("arguments[0].click();", element1);

  2. Если щелкнуть по-прежнему не удается, это может снова означать две вещи:

1. Iframe

Проверьте DOM, чтобы увидеть, живет ли проверяемый элемент в каком-либо кадре. Если это правда, вам нужно будет переключиться на этот фрейм, прежде чем пытаться выполнить какую-либо операцию.

          driver.switchTo().frame("a077aa5e"); //switching the frame by ID
    System.out.println("********We are switching to the iframe*******");
    driver.findElement(By.xpath("html/body/a/img")).click();

2. Новая вкладка

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

      String parent = driver.getWindowHandle();
driver.findElement(By.partialLinkText("Continue")).click();
Set<String> s = driver.getWindowHandles();
// Now iterate using Iterator
Iterator<String> I1 = s.iterator();
while (I1.hasNext()) {
String child_window = I1.next();
if (!parent.equals(child_window)) {
    driver.switchTo().window(child_window);
    element1.click() 
}

Вы также можете попробовать полный xpath, у меня была аналогичная проблема, когда мне приходилось щелкать элемент, который имеет свойство javascript onclick function. полный метод xpath работал, и никаких взаимодействующих исключений не возникало.

Пожалуйста, попробуйте выбрать поле пароля, как это.

    WebDriverWait wait = new WebDriverWait(driver, 10);
    WebElement passwordElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#Passwd")));
    passwordElement.click();
  passwordElement.clear();
     passwordElement.sendKeys("123");

В моем случае элемент, сгенерировавший исключение, был кнопкой, принадлежащей форме. Я заменил

WebElement btnLogin = driver.findElement(By.cssSelector("button"));
btnLogin.click();

с участием

btnLogin.submit();

Моя среда была хромированной Windows 10

В моем случае запрос был недостаточно конкретным. На странице было несколько элементов с одинаковыми атрибутами, поэтому первый найденный элемент оказался не тем, который мне нужен. В результате ошибка «элемент не взаимодействует» была правильной, поскольку я пытался щелкнуть не тот элемент. В итоге я нашел идентификаторы для всех «идентичных» элементов и взял n-й вместо первого. Это объясняет, почему некоторые люди говорят, что им помогло использование xpath.

Примечание. Я использую библиотеку Clojure и Etaoin, которая является оболочкой Selenium, поэтому терминология может не совпадать.

См. упрощенные примеры ниже.

Код с ошибкой, который выдает ошибку «элемент не взаимодействует»:

      (let [submit-button-query {:tag :button :fn/has-class "submit-yes"}
      submit-button-element (query driver submit-button-query)] 
       (click-el driver submit-button-element))  

Рабочий код:

      (let [submit-button-query {:tag :button :fn/has-class "submit-yes"}   ;; query that I assumed was unique and matched the button I was interested in but, in fact, there were multiple elements with that class. I didnt realize it because I was using query fn that only returns the first match. Below Im using query-all fn to find all matches first
      all-submit-button-elements (query-all driver submit-button-query)
      pop-up-submit-button-element (last all-submit-button-elements)] ;; my case was simple and I could safely assume that the button I need is the last one from the list of matches 
   (click-el driver pop-up-submit-button-element))                    ;; successful click 

В моем случае я использую python-selenium. У меня есть две инструкции. Вторую инструкцию выполнить не удалось. Я поставил time.sleep(1) между двумя инструкциями, и все готово.

Если вы хотите, вы можете изменить количество сна в соответствии с вашими потребностями.

Мне пришлось сначала навести курсор на элемент, чтобы появились подэлементы. Я сначала не принял это во внимание.

          WebElement boardMenu = this.driver.findElement(By.linkText(boardTitle));
    Actions action = new Actions(this.driver);

    action.moveToElement(boardMenu).perform();

Еще один совет — проверьте, есть ли у вас один элемент этого DOM. Попробуйте использовать Ctrl+F при просмотре веб-страницы и проверьте там свой xpath; он должен возвращать один элемент, если вы используете метод findElement.

Если он работает в отладке, то должно быть правильное решение.
Я предлагаю использовать явное wait, как указано ниже:

      WebDriverWait wait = new WebDriverWait(new ChromeDriver(), 5);
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#Passwd")));

У меня была та же проблема, но я выяснил причину. Я пытался ввести тег диапазона вместо тега ввода. Мой XPath был написан с тегом span, что было неправильно. Я просмотрел HTML-код элемента и обнаружил проблему. Все, что я тогда сделал, - это нашел тег ввода, который оказался дочерним элементом. Вы можете ввести поле ввода только в том случае, если ваш XPath создан с входным тэгом.

Я собираюсь оградить свой ответ следующим: я знаю, что это чушь ... и должен быть способ получше. (См. Ответы выше) Но я попробовал все предложения здесь и все равно не получил. Закончил погоню за ошибками, разорвав код на биты. Затем я попробовал это:

      import keyboard    
keyboard.press_and_release('tab')
keyboard.press_and_release('tab')
keyboard.press_and_release('tab') #repeat as needed
keyboard.press_and_release('space') 

Это довольно невыносимо, и вы должны следить за тем, чтобы не потерять фокус, иначе вы будете просто табуляция и интервал не в том месте.

Мое предположение о том, почему другие методы не сработали для меня, заключается в том, что я пытаюсь нажать на то, что разработчики не хотели, чтобы бот нажимал. Так что я не нажимаю на нее!

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

Поле появляется на моей странице примерно так.

      <label>
  <input name="generic" type="checkbox" ... >
<label>

Общий рабочий код выглядит примерно так:

      var checkbox = driver.FindElement(By.Name("generic"), mustBeVisible: false);
checkbox.Selected.Should().BeFalse();
var label = checkbox.FindElement(By.XPath(".."));
label.Click();
checkbox.Selected.Should().BeTrue();

Вам нужно будет перевести это на свой конкретный язык. Я использую C # и FluentAssertions. Это решение работало для меня с Chrome 94 и Selenium 3.141.0.

Я получил эту ошибку, потому что использовал неправильный селектор CSS с функцией Selenium WebDriver Node.js By.css().

Вы можете проверить правильность выбора, используя его в веб-консоли своего веб-браузера (сочетание клавиш Ctrl+Shift+K) с помощью функции JavaScript. document.querySelectorAll().

Другие вопросы по тегам