3

This is an element from Gmail, exactly the "Compose" button. Look the id, it is ":il" when i don't have unread messages.

<div id=":il" class="aic">
<div class="z0">
<div class="T-I J-J5-Ji T-I-KE L3" tabindex="0" role="button" style="-moz-user-select: none;" gh="cm">COMPOSE</div>
</div>
</div> 

Now I just sent an email to myself, and log off my account and log in again. When I inspect the element the id has changed to ":3l".

<div id=":3l" class="aic">
<div class="z0">
<div class="T-I J-J5-Ji T-I-KE L3 T-I-JO" tabindex="0" role="button" style="-moz-user-select: none;" gh="cm">COMPOSE</div>
</div>
</div>

Then i read the mail, log off and log in again. When i read the element i am getting the original id ":il".

Why does Gmail change id elements of some elements? I am working with WebDriver and Java and this is driving me crazy. May be I have to change the way to locate this element.

Best Regards!

Added my test coded:

public static void main(String[] args) 
{
    WebDriver driver;
    String baseUrl;

    driver = new FirefoxDriver();
    baseUrl = "https://www.google.com.ar/";
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

    driver.get(baseUrl + "/?gfe_rd=cr&ei=Tf_YVKv1G6yB8Qe_24HYDA&gws_rd=ssl");
    driver.findElement(By.linkText("Gmail")).click();
    driver.findElement(By.id("Passwd")).clear();
    driver.findElement(By.id("Passwd")).sendKeys("Not neccesary :D");
    driver.findElement(By.id("Email")).clear();
    driver.findElement(By.id("Email")).sendKeys("Not_neccesary_:D");
    driver.findElement(By.id("signIn")).click();

    //APARENTLY THERE ARE PROBLEMS WHEN I HAVE MESSAGES UNREADED

    driver.findElement(By.xpath("//div[.='COMPOSE']")).click();
    driver.findElement(By.id(":uv")).sendKeys("Not_neccesary_:D@gmail.com");
    driver.findElement(By.id(":ul")).sendKeys("Test");
    driver.findElement(By.id(":vn")).sendKeys("aaaaaaaaaaa");
    driver.findElement(By.id(":ub")).click();

    driver.close();
}
Nico
  • 374
  • 2
  • 4
  • 17
  • 1
    Those `ids` are dynamically generated. What do you mean by why they are changing? – Saifur Feb 11 '15 at 01:59
  • @Saifur Probably the ids are dynamically generated, i don't know much about HTML. I am learning WebDriver by my own. I am asking why the "id" element of "COMPOSE" button is changing when I don't have unread message and a unread message. – Nico Feb 11 '15 at 02:05
  • Yes. There are a lot of techniques with `html` . probably using them to locate the elements are not best idea. Provide your test ode I will write `xpath` or `cssSelector` for you – Saifur Feb 11 '15 at 02:08

3 Answers3

2

Gmail is NOT supposed to be automated using WebDriver. They have deliberately made ids dynamic for this very reason. Also do you work for google? Are you testing gmail for google? If not using WebDriver to automate gmail doesn't make sense to me and is just waste of time.

Are you testing something in your app that sends email and you want to make sure the email is sent, you want to validate the content or may be click on link or something? The best way to do such things are in background using libraries like JavaMail and using Gmails pop3 server. This approach will give you consistent results and would be significantly faster. You don't have to launch browser, interact with elements etc. also you could support any email provider not just Gmail as long as you have their pop3 server details.

Check my answer to a similar question here

Community
  • 1
  • 1
nilesh
  • 14,131
  • 7
  • 65
  • 79
  • Hello. I am not working for Google. I am learning WebDriver by my own and practicing with my Gmail account. May be I selected the worst page to learn as you suggest. Do you know why google does that? – Nico Feb 11 '15 at 16:16
  • @Nico I suspected that, yeah Gmail is a trap. Google doesn't want any bots to send emails or update passwords. picking any other simple application on the web will be better. Like for example pick any travel site and play around. – nilesh Feb 11 '15 at 16:29
1

So as I wrote in comment (which has been deleted) xpath not good practice. IF you need to click on 'Compose' button and ovoid using ids in your selector you can use next selector to find 'Compose' btn on the page

driver.FindElement(By.Css(".aic div[role='button']")).click();

works excellent for me.

Andrey Egorov
  • 1,249
  • 1
  • 12
  • 9
  • well, first of all this is my opinion and i'm not insist of using this approach by all users. 1. The are more powerful (for me). Of course xpath can do smth that css can't but this is not problem i think 2. xpath are ugly. Really, some of xpaths too long and very difficult to understand which element you are trying to select. Also very difficult to maintain xpaths (i'm talking about using them in automated tests) 3. Selenium recommends css selctors =) 4. And the main argument for me, very simple syntax. Well, these arguments most important for me. – Andrey Egorov Feb 11 '15 at 09:34
  • Possibly i forget smth to describe before and let me remember that this opinion is only mine. For me css selectors the most powerful thing (especially then you know all it's features/possibilities). – Andrey Egorov Feb 11 '15 at 09:36
  • XPath is as ugly as the person who wrote it. CSS can be just as ugly if badly created (ie. take the CSS generated by chrome for this input box; #add-comment-28446852 > table > tbody > tr:nth-child(1) > td:nth-child(1) > textarea), nothing pretty about that. Now I know I could create a far better css selector using my experience but in that same way I can create good xpath. Xpath is a good choice for scenarios in which CSS cannot achieve such as text matching, dom walking, more supportive indexing etc. – Robbie Wareham Feb 11 '15 at 13:41
  • Sure use CSS as first choice but don't be afraid of XPath, it can actually save you from making multiple css selectors and iterative loops. – Robbie Wareham Feb 11 '15 at 13:56
  • RobbieWareham, i know xpaths ) and css ). And as i said xpath can do that css can't . But for me best choice now is css (i'm not reject using of xpaths at all ) – Andrey Egorov Feb 12 '15 at 03:09
  • Nico, you can read about css selectors more here http://www.w3schools.com/cssref/css_selectors.asp and here https://saucelabs.com/resources/selenium/css-selectors. ".aic" means that we search for element with class "aic". "." - means class identificator. – Andrey Egorov Feb 12 '15 at 03:12
0

As I said those are dynamically generated ids. In this kind of scenario I always prefer xpath with explicit wait. I would use the xpath text based search.

//div[.='COMPOSE']

This, search for any div element with COMPOSE as text

Saifur
  • 16,081
  • 6
  • 49
  • 73
  • Thanks. But now I am getting problem with the next line. (driver.findElement(By.id(":uv")).sendKeys("Not_neccesary_:D@gmail.com"); . That's because i don't see anymore the compose windows :S. – Nico Feb 11 '15 at 02:42
  • May i have to add some "wait" command before that instruction. (?) – Nico Feb 11 '15 at 02:53
  • You gotta give me the `html` using `id` or class name not a very good idea I guess – Saifur Feb 11 '15 at 03:02
  • Try `//div[.='Recipients']` xpath – Saifur Feb 11 '15 at 03:08