Check if login was successful with Selenium - 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

Related

Key.ENTER on an input does not submit

I'm trying out Karate and have a use case where I need to trigger a search in a search box and there is no button to trigger the search, so it needs to be triggered via the enter key.
I have tried multiple different flavours of trying to provide Key.ENTER to the input to get it to work but none of them triggers it.
I am using the latest binary with a very basic feature file (altered to use google rather than an internal app URL):
Feature: Trigger search with enter
Background:
* configure driver = { type: 'chrome'}
Scenario: Trigger Google search with enter
Given driver 'https://google.com'
# 1: Attempting to search with enter as an array argument
When input('input[name=q]', ['karate dsl', Key.ENTER])
# 2: Attempting to search with enter as a second command
#When input('input[name=q]', 'karate dsl')
#When input('input[name=q]', Key.ENTER)
# 3: Attempting to search using similar approach to 1 but with a submit
#When submit().input('input[name=q]', ['karate dsl', Key.ENTER])
Then waitFor('{h3}intuit/karate: Test Automation Made Simple - GitHub')
When using any of these approaches (by running ./karate <PATH_TO_ABOVE_FEATURE_FILE>) the search results page never loads so the result (the h3) can never be found...what am I doing wrong?
This is a bug for type chrome. It will actually work for type chromedriver.
Opened an issue: https://github.com/intuit/karate/issues/1192
For now please workaround by using a click on the appropriate button / control etc.

GMail - waiting for the page for fully loaded

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();
}

how to Pass command line argument ( baseURL) for selenium WebDriver

Kindly help.
i have created a runnable jar for my Selenium webDriver suite. now i have to test this in multiple environment( QA , Demo box, Dev ). But my manager doesnt what it to be hard coded like below
driver.get(baseUrl)
As the baseURl will change according to the need. My script is given to the build team. So all they will do in the command prompt is
java -jar myproject-1.0.1.jar
So my manager has asked me to send the baseUrl as a command line argument so that build team do not have to go to my script and manually change the baseUrl. They should be able to change the URL every time they run the script from the command line itself. Something like this
java -jar myproject-1.0.1.jar "http://10.68.14.248:8080/BDA/homePage.html"
Can somebody please guide me through this. Is it possible to send command line arguments to Selenium Web Driver driver.get(baseUrl)
Thanks in advance
From your question above I recon you want pass URL at runtime, means your URL changes time to time so beside hardcoded URL , you want pass at the time your automation code runs. So, let me give you 2 simple solutions.
You can send URL dynamically or at Run time by using javascript executor:
try{
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("var pr=prompt('Enter your URL please:',''); alert(pr);");
Thread.sleep(15000L);
String URL = driver.switchTo().alert().getText();
driver.switchTo().alert().accept();
driver.get(URL);
}catch(Throwable e)
{
System.out.println("failed");
}
Use this code in place of driver.get(); , so that a prompt box will appear when you run your code and within 15 secs or it will throw a error(you can change the time in Thread.Sleep) you will give the current Valid URL and hit Enter, the navigation will go to the URL. So that you can use different URL for same set of testscripts.
By using Scanner Class:
String url = "";
System.out.println("Enter the URL :");
Scanner s = new Scanner(System.in);
url = s.next();
s.close();
By using this you can give needed URL in your Console (If you are using Eclipse).
I recommend try Javascript excutor in your code and then create a runnable jar file and just run the Jar file, you will know and it will be the better solution than commandline URL passing . Let me know :)
Another way is to supply arguments this way -Durl=foobar.com and extract them in runtime like this
String URL= System.getProperty("url")

unexpected behaviour in Appium

I am new in appium. I am running following test for IOS
#Test
public void Login() throws InterruptedException{
Thread.sleep(3000);
driver.findElement(By.xpath("//window[1]/textfield[9]")).sendKeys("john");
driver.findElement(By.xpath("//window[1]/secure[1]")).sendKeys("asdf1234");
driver.findElement(By.name("btn checkbox")).click();
driver.findElement(By.name("Login")).click();
Thread.sleep(6000);
here it works fine, it logins, but when I comment driver.findElement(By.name("btn checkbox")).click(); this line it does not login, but shows test is passed, there is no single exception
please can anybody tell me what is problem here?
It seems that your test doesn't check if it's logged in or not. You're performing the actions to make it login, but you're not actually validating anything. You're smoke testing.
What you want to do here...
Build something that lets you check for any indicator that you have finished the login process. (like welcome label!)
Use an explicit wait to do this.
Define your success criteria. Login usually takes 10 seconds. Our success criteria may be anything under 25 seconds.
If it doesn't find the element after 25 seconds in the exception that's thrown (TimeoutException), you should return something like "None", else return the element.
Should look something like this:
WebElement welcomeLabel = (new WebDriverWait(driver, 25))
.until(ExpectedConditions.presenceOfElementLocated(By.name("welcomeLabel")));
And then you'll say something like this:
Assert.assertIsNotNone(welcomeLabel) this assertion is what makes this NOT a smoke test
Of course that's happening. The only thing you do is clicking on that button. Appium is doing exactly that, doesn't encounter any problem, and returns a 'test passed'.
You have to write some kind of a test yourself, to know if you're logged in or not.
For example by searching for a logout button at the next page.
Example:
Assert.assertTrue(wd.findElement(By.name("Logout")).isDisplayed());

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.