GMail - waiting for the page for fully loaded - selenium

I am trying to automate gmail page (for some kind of email verification), after input username and password, I want to wait the page to fully loaded before continuing to my next action.
This is what I tried:
Selenium2Library.Input Text //input[contains(#id, "identifierId")] ${local_email_username}
Selenium2Library.Click Element //span[text()="Berikutnya"]
Sleep 2s
Selenium2Library.Wait Until Element Is Visible //input[contains(#name, "password")] timeout=30s
Selenium2Library.Input Password //input[contains(#name, "password")] ${local_email_password}
Selenium2Library.Click Element //span[text()="Berikutnya"]
Sleep 2s
Selenium2Library.Wait Until Element Is Visible //input[contains(#aria-label, "Search")] timeout=30s
### should be logged in to gmail
Log >>> logged in to gmail. sleeping..
Sleep 5s
### make sure the email page fully loaded
Log >>> making sure the email page fully loaded.. waiting new conversation button appeared
Comment Wait Until Keyword Succeeds 10x 2s Selenium2Library.Page Should Contain ${email_name}
Wait Until Keyword Succeeds 20x 3s Selenium2Library.Page Should Contain Element //button[contains(#title, 'New conversation')]
Log >>> email page fully loaded. start searching activation email...
What I want to achieve is waiting for the new conversation button, that indicates that page is fully loaded (//button[contains(#title, 'New conversation')])
The problem is the script never finds the button. I tried to inspect and search for that xpath, and the element found.
Is there any solution for that?
Update:
i tried using Select Frame like this.. like #Gaurav said.. here's the code:|
Selenium2Library.Select Frame ${iframe_locator}
Wait Until Keyword Succeeds 20x 3s Selenium2Library.Page Should Contain Element //button[contains(#title, 'New conversation')]
Selenium2Library.Unselect Frame
where ${iframe_locator} is //body/div[7]/div[3]/div[1]/div[2]/div[1]/div[1]/div[3]/div[1]/div[1]/div[2]/div[1]/iframe[2]
but still no luck

The button is in iFrame, so you need to switch to that iFrame(there might be more iframes, so you need to switch to that specific one) and the look for //button[contains(#title, 'New conversation')]
Here is Corresponding Java Implementation
#Test
public void newConversation() throws IOException, InterruptedException{
driver.get("https://www.google.com/intl/hi/gmail/about/");
driver.findElement(By.linkText("प्रवेश करें")).click();
driver.findElement(By.id("identifierId")).sendKeys("*********#gmail.com");
driver.findElement(By.id("identifierNext")).click();
Thread.sleep(30000);
driver.switchTo().frame(5);
WebElement element = driver.findElement(By.xpath("//div[contains(#aria-label,'Change profile picture')]"));
Actions action = new Actions(driver);
action.moveToElement(element).build().perform();
driver.findElement(By.xpath("//button[contains(#title,'New conversation')]")).click();
}

Related

GEB assertion, waitFor

I'm learning GEB in IntelliJ and have two issues.
When I click button on the top of the page I'm redirected to very bottom of the page.
After this I need to do assertion that the site slided down.
I try to do assertion in this example:
assert page.element_on_the bottom.isDisplayed() == true
// element_on_the bottom {$('css_selector)
The above assertion always returns true even I don't click button to slide down.
I need to check if element is visible on the part of website which is actually displayed on my monitor screen. Is there a way to do this?
I try to use waitFor statement in example:
waitFor{page.element.isDisplayed()}
but it doesn't work:
geb.waiting.WaitTimeoutException: condition did not pass in 5.0 seconds (failed with exception)
instead of this I use:
Thread.sleep(3000) //which is not desirable here
and then my test passes. I think my element don't trigger any js or ajax script actions.
I'm not sure how to use waitFor that should wait for all elements to load.
Element doesn't have to be in view for is isDisplayed() to return true - it will return true as long as the element is visible on page, e.g. it's display property is not set to hidden. You will need to detect your scroll position using javascript because WebDriver does not expose scroll information. See this response for how to detect that scroll is at the bottom of the page and see this section of the Book of Geb for how to execute javascript code in the browser.
What is the exception and its stacktrace that you're getting from your waitFor {} call? It probably contains the clue on what is actually going on.
For your first problem, can you please try the following as displayed should work fine for the visibility and present should be good to check the presence of the css selector in the DOM:
waitFor { page.element_on_the bottom.isDisplayed() }
or
waitFor { page.element_on_the bottom.displayed() }
For the second problem, you need to edit your Gebconfig file, like below as the waiting time you have right now is 5 seconds that's why it's failing whereas your sleep time is way more than 5 seconds:
waiting {
timeout = 30
retryInterval = 0.1
}
or, you can also try that at the same line of the code as below:
waitFor (30, 0.1) {page.element.isDisplayed()}
Please let us know if that worked fine or not! On another note, why don't you simply write the function name from the imported class instead of always writing className.functionName()? Best of luck and Cheers!!

Wait for an element using Selenium webdriver

What is the best way to wait for an element to appear on a web page? I have read that we can use implicit wait and functions like webdriverwait, fluentwait etc and last but not the least thread.sleep()...which i use the most but want to stop using at all.
My scenario:
User logs in to a website...website checks the credentials and provides an offer to the user in the form of an overlay (kind of popup but not a separate window). I need to verify text on the the overlay.
There is a time gap between user signing in and the overlay getting displayed. what is the best approach so that selenium waits only till the time the element is not visible. As the overlay is not a separate page but part of the main page, implicit wait does not work at all.
All suggestions are welcome...:)
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(By.id("optionsBuilderSelect_input")));
I'm a professional scraper (http://nitinsurana.com) I've written 30+ softwares using selenium and I've never faced any such issue, anyways above is a sample code.
All I can think of is that what until condition has to be checked because many a times elements are already visible, but they are not clickable and things like that. I guess you should give different options a try and I hope you'll find the one required.
Always start by using a implicit wait. I think Selenium defaults to 5 seconds and so if you do a driver.findElement(), the implication is that it will wait up to 5 seconds. That should do it. If you are experiencing a scenario where the time it takes is unpredictable, then use FluentWait (with the same 5 second timeout) but also using the .ignoring method and wrap that inside a while loop . Here is the basic idea:
int tries=0;
while ( tries < 3 ) {
//fluent wait (with .ignoring) inside here
tries ++1;
}
public boolean waitForElement(WebElement ele, String xpath, int seconds) throws InterruptedException{
//returns true if the xpath appears in the webElement within the time
//false when timed out
int t=0;
while(t<seconds*10){
if(ele.findElements(By.xpath(xpath)).size()>0)
return true;
else{
Thread.sleep(100);
t++;
continue;
}
}
System.out.println("waited for "+seconds+"seconds. But couldn't find "+xpath+ " in the element specified");
return false;
}
You could wait for the presence of the element to appear as follows:
new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.id("someId")));

Check if login was successful with Selenium

I'm just getting to grips with Selenium, and have made a simple log in script using the Firefox IDE.
What want to do now is check if the log in was successful.
The simplest way I could think of was to search for a piece of text that is only visible after log in i.e. Hi, [account name].
But I'm a little unsure on how to do this with Selenium.
Is there a way you can search for a term on a page and then act, upon its presence?
Also, is this the best way to check if your logged in?
1) Yes, I am checking for sucessful login by the way that I search for specific label. In my case that label contains ID of logged in user. Example:
<span id="username">PAVEL007</span>
So, when I log in:
driver.get("http://PAVEL007:OmgTooSecretToTellYou!#my-test-site.com");
Then I search for that label
WebElement loggedInUser = driver.findElement(By.id("username"));
And verify that I am in:
Assert.assertEquals(loggedInUser.getText(),"PAVEL007");
In nutshell:
If your website shows some specific text visible only after sucessful login, use that text
Best way is not to search for that text itself, but for element containing the text
NOTE
The driver variable is assumed healthy, living instance of WebDriver
My pseudo code is Java based
Get a url which can be accessed only after login.
url = "some url accessed only after login"
driver.navigate_to url
driver.current_url == url ? "logged_in" : "not_logged_in"
if not logged in it will be redirected to some other url. This is applicable in websites where url is not created dynamically
If you're using the IDE it should be a simple case of recording your login action and then where you have your Hi [username] element, right-click on it and then in the context menu you should see additional options that are from the IDE.
One of those should be verify text or assert text. Select that, when you then run your test case it will complete the login account and verify/assert that the Hi [username] text is on the page.
If you are using selenium IDE, it should very easy case, first of all you have to recording your login action and after login you have Hi [username] text is present on the screen, right-click on that text then select verifytext in the the context menu you should see additional options that are from the IDE.
One of those should be verify text or assert text. Select that, when you then run your test case it will complete the login account and verify/assert that the Hi [username] text is on the page
open | www.gmail.com
type | id=username |usrename
type | id=password |password
Verifytext | HI[Username]|
The obvious answer is the fluent method:
driver.getSource().contains("a string");
Personally, I prefer using cssLocator to locate values:
if ( driver.findElement(myElement).getText().equalsIgnoreCase("my value") ) //do
Verify successful login through assertion. This is my code you can verify
WebElement useremail = driver.findElement(By.xpath("//input[#placeholder='Email']"));
WebElement password = driver.findElement(By.xpath("//input[#placeholder='Password']"));
WebElement login = driver.findElement(By.xpath("//a[#class='btn-signin']"));
useremail.sendKeys("abc#mailinator.com"); password.sendKeys("XXX");
login.click(); String actualurl="url";
String expectedurl= driver.getCurrentUrl();
Assert.assertEquals(expectedurl,actualurl);
You can use WebDriverWait of selenium.webdriver.support.ui to wait for login.
from selenium import webdriver
from selenium.webdriver.support import ui
wait = ui.WebDriverWait(driver, 60)
wait.until(lambda driver: driver.find_elements_by_tag_name('fieldset')) # there is also a until_not do the not condition
# do something after the login, if not login after 60 there will throw timeout exception

Explicit in selenium

I am using Selenium to get div value, but the fallowing code is not waiting for the page, just for URL. I used time.sleep, which is very primitive and totally not flexible. I want to change it on the explicit, but I am not too experienced in Python and I have a problem with that.
The website name has been changed just in case :
def repeat():
import wx
while True:
botloc = driver.find_element_by_id('botloc').text
print botloc
botX,botY = map(int,botloc.split(','))
print botX
print botY
wx.Yield()
def checker():
if driver.current_url == 'logged.example.com':
time.sleep(5)
repeat()
else:
checker()
checker()
How can I replace time.sleep with something flexible to wait the shortest time as possible after the page will be loaded? How to use explicit correctly with my code?
I know that's possible with using an element from the website, but I can't write anything sensible, I just need an example.
Is possibility to use element_by_id('botloc') for wait till it will be visible then start repeat() ?
How can i replace time.sleep with something flexible to wait shortest
time as possible after the page will be loaded?
I suppose you use get(url) to load the page. Generally you don't have to do anything, WebDriver automatically waits until page is being loaded. So you can remove time.sleep(). However there are some issues reported when loading the page using get with firefox driver, because of that you will have to wait for some target element which is supposed to be in the loaded page as mentioned below.
How to use explicit correctly with my code?
Have you checked Selenium webdriver documentation ? you can wait for botloc element explicitly as below
//assuming you have a valid webdriver reference
//Ex: DEFAULT_WAIT = 10 means
//waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds.
element = WebDriverWait(webdriver, DEFAULT_WAIT).until(EC.presence_of_element_located((By.ID, "botloc")))
Refer this page for more information

Cucumber + Capybara tests to ensure a new window is opened

I have the following lines in my feature file:
Given I have website "www.google.co.uk"
When I click the website "www.google.co.uk"
Then "www.google.co.uk" page is opened in a new window
I am struggling to find a way to test that the webpage is definately opened in a new window.
Currently I have been using this in my step def:
Then /url "([^"]*)" is opened in new window/ do |url|
browser = page.driver.browser
current_id = browser.window_handle
tab_id = page.driver.find_window(url)
browser.switch_to.window tab_id
page.driver.browser.close
browser.switch_to.window current_id
end
but this still passes the test if the webpage is loaded on the same page, I want it to fail if the webpage is loaded on the same window/tab.
Any suggestions?
Many thanks
I see no assertions in your test.
My approach would be to test size of window_handles array after performing clicking action on the link, since before clicking the size should equal 1 and after the clicking window_handles should equal 2.
assert page.driver.browser.window_handles.size == 2
Imho, good enough, since if the webpage is loaded in the same tab, the size will be 1 and the test will fail.