0

I'm trying to do a little gmail automation. What my code does is compose an email and then I'm trying to select the textareas (subject, body, recipients) using the IDs that I copied from the HTML source. These IDs work while I'm getting to the gmail page but stop working when I try to access the textareas.

System.out.println(driver.getTitle());
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(":3tx")));
    sign = driver.findElement(By.id(":3tx"));
    sign.sendKeys(recipient);

Then I get this error:

Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.id: :3tx (tried for 5 second(s) with 500 MILLISECONDS interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:80)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:232)
at Email.sendEmail(Email.java:42)
at Email.main(Email.java:60)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.id: :3tx

https://i.stack.imgur.com/u02cU.jpg <= Where I'm pulling the ID value from

  • Possible duplicate of [Selenium "selenium.common.exceptions.NoSuchElementException" when using Chrome](https://stackoverflow.com/questions/47993443/selenium-selenium-common-exceptions-nosuchelementexception-when-using-chrome) – undetected Selenium May 09 '18 at 21:18
  • When you say these ids work until you get to the page, does that mean that some IDs gotten by this method work? Or these exact IDs are present elsewhere and are usable before opening up the compose widget? – Julian May 09 '18 at 21:52
  • Other IDs have been used with this method and have worked, for instance those to input into the username and password – Ronoc Eroom May 09 '18 at 21:53
  • Okay, that's less useful. This ID doesn't ever work even if some others do, because each ID is an unrelated concern. It's common to have some IDs work by a method, and some not. So lets break away from any notion of what should work based on what other unrelated IDs pointing to elements have done. Have you tried doing driver.findElements (the plural version). There's a chance that the ID isn't as unique as it should be, and the first instance being found is never going to be visible within the task you're performing. – Julian May 09 '18 at 21:57
  • I just tried it, and FindElements is returning an empty list – Ronoc Eroom May 09 '18 at 22:01
  • What I would try to do to help understand this problem, is to start targeting parent elements, start with maybe the immediate parent, if you can't access that, go up a parent higher. Find the nearest parent you can target and interact with, then use that parent to build a css selector to explicitly crawl back down to your desired element. See if you can access it then, if you can, then your locator is the problem. If you still can't, go back up to a parent inbetween, rinse, repeat. – Julian May 09 '18 at 22:01
  • Another small possibility is that because google likes to do weird things, given that the ID you describe might not be intended to be human readable, it could be dynamically generated, which means it could periodically change. So if you rely on that ID or other html attributes to locate elements, they could be changing up from under you without warning (not probable, but this is something that happens under some web technologies) – Julian May 09 '18 at 22:04
  • I'll look into the first suggestion some more, I dug some more into it and saw that it was "aria-hidden" which seems to be there specifically to prevent non-human users from accessing it – Ronoc Eroom May 09 '18 at 22:06
  • You were correct the ID changes whenever a new "Compose" is called so I'm now working on accessing something other than the ID. Thanks for your help! – Ronoc Eroom May 09 '18 at 22:43

1 Answers1

0

If the element is visible, waiting on visibilty will fail. try this:

System.out.println(driver.getTitle());
    try {wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(":3tx")));} catch (TimeoutException e) {}
    sign = driver.findElement(By.id(":3tx"));
    sign.sendKeys(recipient);
pburgr
  • 1,722
  • 1
  • 11
  • 26
  • Thanks for you help! The problem turned out to be that the id is created each time the page is loaded so when I would call By.ID the ID I had previously put in no longer existed – Ronoc Eroom May 16 '18 at 13:14
  • I had the same problem in mailinator.com, where no way to know the right ID. If at least part of the ID is always same, you can use xpath to find all the elements. This is piece of code I use to mark all messages in mailinator inbox: List boxes = driver.findElements(By.xpath("//i[contains(@id,'checkoff')]")); for(WebElement box: boxes) {box.click();} – pburgr May 17 '18 at 06:35