How to verify and assert nonvisible Icon via Selenium? - java

I have a situation- I want to write a test when a particular User Logs in, he should not see Budget Icon. Budget icon is obviously not available when he's logged in. So I want to make sure that its working right though assertion. I am confused how should I do it ..I am using Page Object Model and I am trying below: using isDisplayed method
Below is my Base class:
public class LaydownHomePage extends TestBase {
#FindBy(xpath="//nav[#id=\"mainnav-container\"]/div[2]/a[2]")
WebElement budgeticon;
public LaydownHomePage () {
PageFactory.initElements(driver, this);
}
public boolean CheckIfBudgetIconIsAvailable ()
{
return budgeticon.isDisplayed();
}
}
And this is my Test class:
public class VerifyLaydownBudgeticon extends TestBase
{
LoginPage loginpage;
LaydownHomePage homepage;
public VerifyLaydownBudgeticon()
{
super();
}
#Test(priority=1)
public void setUp()
{
//TestBase base= new TestBase();
initialization();
loginpage= new LoginPage();
loginpage.loginToBase(prop.getProperty("username"),prop.getProperty(
"password"));
homepage=loginpage.changeLogin();
}
#Test(priority=2)
public void BudgetIconDisplayed (){
// Assert.assertTrue(false);
Assert.assertEquals(true, homepage.CheckIfBudgetIconIsAvailable());
}
}

Related

Java (Selenium) - super class constructor to initialise sub classes

PageOne and PageTwo both need to make use of MasterPage methods (eg click Ok). I'm trying to initialize both pages within the constructor of MasterPage.
IntelliJ tells me to either add super(driver) to the Page1/Page2 constructors, or to add a no arg constructor to master. In both cases, the tests can't run. with a super(driver) constructor, the pages fail to initialize, and in the no arg constructor, the clickOk() method fails when called from the Page1/Page2 method.
MasterPage:
public class MasterPage {
private WebDriver driver;
public Page1 p1;
public Page2 p2;
public MasterPage(WebDriver driver) {
this.driver = driver;
p1 = new Page1(driver);
p2 = new Page2(driver);
PageFactory.initElements(driver, this);
}
#FindBy(id = "OkBtn")
private WebElement okBtn;
public void clickOk() {
okBtn.click();
}
}
Page1:
public class Page1 extends MasterPage {
private WebDriver driver;
public Page1(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
#FindBy(id="field")
private WebElement elementOne;
public void completePage() {
elementOne.click();
clickOk();
}
}
Page2:
public class Page2 extends MasterPage {
private WebDriver driver;
public Page2(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
#FindBy (id="field")
private WebElement elementTwo;
public void completePageTwo() {
elementTwo.click();
clickOk();
}
}
My intention is to utilise them like this:
public class Page1Steps {
MasterPage master;
WebDriver driver;
public void testMethod() {
master = new MasterPage(driver);
master.p1.completePage();
master.p2.completePageTwo();
}
}
You may be able to tell, I'm not 100% sure of the best way to approach this problem, so any guidance would be really appreciated.
First of all, MasterPage shouldn't know about page1 and page2, it's their base class. You also don't need driver in each one of the derived Page, you can hold it in the parent MasterPage.
The problem is MasterPage constructor receives WebDriver parameter, but you don't have call to super(driver) in the derived classes constructors.
I also suggest each method which navigates the test to the another page will return this new page
MasterPage:
public class MasterPage { // can be abstract
protected WebDriver driver;
public MasterPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
#FindBy(id = "OkBtn")
private WebElement okBtn;
protected void clickOk() {
okBtn.click();
}
}
Page1:
public class Page1 extends MasterPage {
public Page1(WebDriver driver) {
super(driver);
}
#FindBy(id="field")
private WebElement elementOne;
public Page2 completePageAndGoToPageTwo() {
elementOne.click();
clickOk();
return new Page2(driver);
}
}
Page2:
public class Page2 extends MasterPage {
public Page2(WebDriver driver) {
super(driver);
}
#FindBy (id="field")
private WebElement elementTwo;
public void completePageTwo() {
elementTwo.click();
clickOk();
}
}
Page1Steps:
public class Page1Steps {
public void testMethod() {
Page1 pageOne = new Page1(driver);
pageOne
.completePageAndGoToPageTwo()
.completePageTwo();
}
}

Selenium Java base class for all browser drivers and code which is redundant

I am new in Selenium and Java and I need help with base class. I have I base where I set methods for driver browsers and for its close. Problem is that when I call these method from main always web driver is called and browser is open many times. What is best practice if I don't want to have code duplication
and I want a good structure of project.
Main:
public class Main extends TestBase {
public static void main(String[] args) throws InterruptedException, ClassNotFoundException, SQLException {
LoginTest LoginTest = new LoginTest();
LogofTest LogofTest = new LogofTest();
TestBase TestBase = new TestBase();
LoginTest.setUpBeforeTestMethod();
LoginTest.loginAsAdmin();
LogofTest.logofAsAdmin();
LoginTest.tearDownAfterTestClass();
}
}
TestBase:
public class TestBase {
String a = System.setProperty("webdriver.chrome.driver",
"path");
WebDriver driver = new ChromeDriver();
protected WebDriver setUpBeforeTestClass() {
return driver;
}
protected void setUpBeforeTestMethod() {
driver.get("website");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void tearDownAfterTestClass() {
driver.close();
}}
LoginTest:
public class LoginTest extends TestBase {
public void login() throws InterruptedException {
WebElement username = driver.findElement(By.name("username"));
username.sendKeys("username");
}
}
The main focus is that I don't want to write again
WebDriver driver = new ChromeDriver();
driver.get("website"); System.setProperty("webdriver.chrome,"path");
for each test in function or class. So I want to create base class and inherit from it.
Example Selenium Test with JUnit using the Page Object Model
TestBase
public class TestBase
{
private String a = System.setProperty("webdriver.chrome.driver", "path");
protected WebDriver driver;
#Before //Before each test case, use BeforeClass for before each test class
public static void setUpBeforeTestCase() {
driver = new ChromeDriver();
driver.get("website");
}
#After
public static void tearDownAfterTestCase() {
driver.Quit(); //driver.Close() closes the window, but doesn't properly dispose of the driver
}
}
LoginTest:
public class LoginTest extends TestBase {
#Test
public void loginAndOutAsAdmin(){
LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
LandingPage landingPage = loginPage.login("adminUser", "adminPassword");
landingPage.logout();
//Do some sort of assert here that you are logged out
}
}
BasePage
public class BasePage
{
protected WebDriver driver;
//Other common stuff your Page Objects will do, like wait for an element
}
LoginPage
public class LoginPage extends BasePage
{
#FindBy(how = How.NAME, using = "username")
private WebElement usernameBox;
//something for passwordBox and loginButton
public LoginPage(WebDriver currentDriver)
{
driver = currentDriver;
}
public LandingPage login(String username, String password)
{
usernameBox.sendKeys(username);
passwordBox.sendKeys(password);
loginButton.click();
return PageFactory.initElements(driver, LandingPage.class);
}
}
I haven't tried to compile this, but that's the basic idea. I'll let you fill in the details.

Class which create object of classes

I'm new and I'm learning webdriver and java:)
I have beginner question.
I created classes whit locators(findBy) and methods working with this locators (senKeys(), click(), etc.) - I use pagefactory.
HomePage
LoginPage
...
My main class AddNewLeadTest is a class where i initialize method from classes with locators, and I do it like this:
HomePage hp = new HomePage(driver);
hp.loginButton.click()
I would like do to this like this:
HomePage.loginButton.click()
It's faster and I will not have to create in AddNewLeadTest new object for everyone xxxPage class.
How should I write class/method to simplify creating new object?
I found example I would like to use in my project(in C#), but I don't know how to use it in Java. See below.
public static class Pages
{
private static T GetPage<T>() where T : new()
{
var page = new T();
PageFactory.InitElements(Browser.Driver, page);
return page;
}
public static AboutPage About
{
get { return GetPage<AboutPage>(); }
}
public static TopNavigationPage TopNavigation
{
get { return GetPage<TopNavigationPage>(); }
}
public static HomePage Home
{
get { return GetPage<HomePage>(); }
}
public static ContactPage Contact
{
get { return GetPage<ContactPage>(); }
}
public static RegisterPage Register
{
get { return GetPage<RegisterPage>(); }
}
public static LoginPage Login
{
get { return GetPage<LoginPage>(); }
}
public static ManageAccountPage ManageAccount
{
get { return GetPage<ManageAccountPage>(); }
}
In this example calling method is like this:
public void CanRegisterNewAccount()
{
Pages.Register.Goto();
Pages.Register.RegisterNewUser();
}
So its very simple and clear.
So how can I write it another way, i think it dont look good..
/*------------------------------------------------------------------------*/
HomePage gotologin = new HomePage(driver);
gotologin.gotoLoginPage();
/*------------------------------------------------------------------------*/
LoginPage login = new LoginPage(driver);
login.loginUserToBase("login","pass");
/*------------------------------------------------------------------------*/
addLeadPage newLead = new addLeadPage(driver);
newLead.gotoLeadsPage();
newLead.addNewLead();
newLead.enterLeadName("Tolek");
newLead.enterLeadLastName("Banan");
newLead.enterLeadTitle("Boss");
newLead.enterLeadEmail("tolekbanan#gmail.com");
newLead.enterLeadMobile("123456789");
newLead.enterLeadWorkPhone("9876541");
newLead.enterLeadStreet("Kowalskiego");
newLead.enterLeadCity("Kraków");
newLead.enterLeadCode("12-123");
newLead.enterLeadRegion("Małopolska");
newLead.enterLeadTag("testBase");
newLead.clickSubmit();
/*------------------------------------------------------------------------*/
LeadPage checkStatus = new LeadPage(driver);
LeadPage.checkUsrStat();
...
...
...
I was inpired by method from my before post from https://www.youtube.com/watch?v=DO8KVe00kcU
I thought that is a solution i should use im my tests
I show U now all part of this test.
Pages.class
public static class Pages
{
private static T GetPage<T>() where T : new()
{
var page = new T();
PageFactory.InitElements(Browser.Driver, page);
return page;
}
** public static LoginPage Login
{
get { return GetPage<LoginPage>(); }
}**
public static AboutPage About
{
get { return GetPage<AboutPage>(); }
}
public static TopNavigationPage TopNavigation
{
get { return GetPage<TopNavigationPage>(); }
}
...
}
LoginPage.class
public class LoginPage
{
public void Goto()
{
Pages.TopNavigation.LogIn();
}
}
TopNavigation.class
[FindsBy(How = How.LinkText, Using = "Log in")]
private IWebElement logInLink;
public void LogIn()
{
logInLink.Click();
}
and AddNewLeadTest.class
public void CanGoToLoginPage()
{
Pages.Home.Goto();
}
Is it really bad solution??

How make webdriver not to close browser window after each test?

I'm new in both Selenium WebDriver and Java. I have some webservices on my site on page /someservice.php. I've wrote few tests on Selenuim and they work fine. Code example (Main Class):
public class SiteClass {
static WebDriver driver;
private static boolean findElements(String xpath,int timeOut ) {
public static void open(String url){
//Here we initialize the firefox webdriver
driver=new FirefoxDriver();
driver.get(url);
}
public static void close(){
driver.close();
}
WebDriverWait wait = new WebDriverWait( driver, timeOut );
try {
if( wait.until( ExpectedConditions.visibilityOfElementLocated( By.xpath( xpath ) ) ) != null ) {
return true;
} else {
return false;
}
} catch( TimeoutException e ) {
return false;
}}
public static Boolean CheckDiameter(String search,String result){
driver.findElement(By.xpath("//input[#id='search_diam']")).sendKeys(search);
WebDriverWait wait = new WebDriverWait(driver, 5);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#class='ac_results'][last()]/ul/li")));
WebElement searchVariant=driver.findElement(By.xpath("//div[#class='ac_results'][last()]/ul/li"));
Actions action = new Actions(driver);
action.moveToElement(searchVariant).perform();
driver.findElement(By.xpath("//li[#class='ac_over']")).click();
Boolean iselementpresent = findElements(result,5);
return iselementpresent;
}
}
Code Example (Test Class)
#RunWith(Parameterized.class)
public class DiamTest {#Parameters
public static Collection<Object[]> diams() {
return Arrays.asList(new Object[][] {
{ "111", "//div[#class='jGrowl-message']",true},
{ "222", "//div[#class='jGrowl-message']",false},
{ "333", "//div[#class='jGrowl-message']",true},
});
}
private String inputMark;
private String expectedResult;
private Boolean assertResult;
public DiamTest(String mark, String result, boolean aResult) {
inputMark=mark;
expectedResult=result;
assertResult=aResult;
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
/**
* Test of CheckDiameter method, of class CableRu.
*/
#Test
public void testCheckDiameter() {
SiteClass obj=new SiteClass();
obj.open("http://example.com/services.php");
assertEquals(assertResult, obj.CheckDiameter(inputMark, expectedResult));
obj.close();
}
}
Now I have 2 tests like that with 3 parameters each (total 6 variants). As you can see in every variant I create new browser window and when I run all 6 variants that take too much time (up to 80 seconds).
How can I run all variants in one browser window to speed up my tests?
Just move contents of public static void close() method from your SiteClass to tearDownClass() method in DiamTest class. In this way the browser window will be closed when the class execution finished (because of #AfterClass annotation). Your code then should look like this:
//DiamTest class
#AfterClass
public static void tearDownClass() {
driver.close();
}
It's also a good practice to move browser window initialization to setUpClass() method which will be executed before each test class (according to #BeforeClass annotation)
//DiamTest class
#BeforeClass
public static void setUpClass() {
//Here we initialize the firefox webdriver
driver=new FirefoxDriver();
driver.get(url);
}
What you need to do is share your help class with all your tests, this mean, you should create an instance of SiteClass inside your setUpClass method.
This method are annotated with #BeforeClass assuring your test class will create this method will be executed before all the test be executed.
You can read more about #BeforeClass in jUnit doc: or have a simple overview in this response.
You will also need do some rewrite some code to allow share the driver with the another test, something like this:
#RunWith(Parameterized.class)
public class DiamTest {
#Parameters
public static Collection<Object[]> diams() {
return Arrays.asList(new Object[][] {
{ "111", "//div[#class='jGrowl-message']",true},
{ "222", "//div[#class='jGrowl-message']",false},
{ "333", "//div[#class='jGrowl-message']",true},
});
}
private String inputMark;
private String expectedResult;
private Boolean assertResult;
private static SiteUtil siteUtil;
public DiamTest(String mark, String result, boolean aResult) {
inputMark=mark;
expectedResult=result;
assertResult=aResult;
}
#BeforeClass
public static void setUpClass() {
siteUtil = new SiteUtil();
}
#AfterClass
public static void tearDownClass() {
siteUtil.close();
}
#Test
public void testCheckDiameter() {
siteUtil.open("http://example.com/services.php");
assertEquals(assertResult, obj.CheckDiameter(inputMark, expectedResult));
}
}
and:
public class SiteClass {
static WebDriver driver;
public SiteClass() {
driver = new FirefoxDriver();
}
public void open(String url){
driver.get(url);
}
...
Tip:
You should read about the TestPyramid.
Since functional tests are expensive, you should care about what is really necessary test. This article is about this.

How do I pass objects between classes

I'm trying to encapsulate a Selenium script by breaking it up into three classes (Grid, Browser, and testCase). I'm able to get the browser to open, but I seem to be missing the connection for the testCase class to interject its commands.
Grid.java
package com.autotrader.grid;
import org.junit.After;
import org.junit.Test;
public class Grid {
Browser browser = new Browser();
TestCase testCase = new TestCase();
public Grid() {
browser.setUp("http://pbskids.org");
}
#Test
public void main() {
testCase.runCase();
}
#After
public void tearDown() throws Exception {
browser.stop();
}
}
Browser.java
package com.autotrader.grid;
import com.thoughtworks.selenium.Selenium;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.concurrent.TimeUnit;
public class Browser {
private String baseUrl;
private String driverNamespace;
private String driverLocation;
private DesiredCapabilities capabilities;
private WebDriver driver;
public Selenium selenium;
// constructor
public Browser() {
}
public DesiredCapabilities getCapabilities() {
return this.capabilities;
}
public String getDriverLocation() {
return this.driverLocation;
}
public String getDriverNamespace() {
return this.driverNamespace;
}
public Selenium getSelenium(){
return selenium;
}
public void open (String url) {
this.selenium.open(url);
}
public void setBaseUrl(String url) {
this.baseUrl = url;
}
public void setCapabilities() {
this.capabilities = DesiredCapabilities.firefox();
this.driver = new FirefoxDriver(capabilities);
}
public void setDriverLocation(String location) {
this.driverLocation = location;
}
public void setDriverNamespace(String namespace) {
this.driverNamespace = namespace;
}
public void setSpeed(String speed){
this.selenium.setSpeed(speed);
}
public void setUp(String url){
setDriverNamespace("webdriver.firefox.driver");
setDriverLocation(System.getenv("ProgramFiles(x86)") + "\\Mozilla Firefox\\firefox.exe");
System.setProperty(driverNamespace,driverLocation);
setCapabilities();
setBaseUrl(url);
this.selenium = new WebDriverBackedSelenium(driver, url);
this.driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
public void stop(){
this.selenium.stop();
}
}
TestCase.java
package com.autotrader.grid;
import com.thoughtworks.selenium.Selenium;
public class TestCase {
Browser browser = new Browser();
Selenium selenium;
// constructor
public TestCase(){
selenium = browser.getSelenium();
}
public void runCase(){
selenium.open("/privacy/termsofuse.html?campaign=fkhp_tou");
selenium.setSpeed("1000");
}
}
So; the driver is setup, I then opened using the Selenium object (in Browser.java), but when I try to interact with the Selenium object (in TestCase.java) it's not picking it up. Thank you for any help.
Instead of:
public class Grid {
Browser browser = new Browser();
TestCase testCase = new TestCase();
public Grid() {
...
Try:
public class Grid {
Browser browser = new Browser();
TestCase testCase = new TestCase(browser); // <-- this line changed
public Grid() {
...
And in here:
public class TestCase {
Browser browser = new Browser();
Selenium selenium;
// constructor
public TestCase(){
selenium = browser.getSelenium();
}
...
Do like this:
public class TestCase {
Browser browser = new Browser(); // <-- this line changed
Selenium selenium;
// constructor
public TestCase(Browser browser){ // <-- this line changed
this.browser = browser; // <-- this line was added
selenium = browser.getSelenium();
}
...
I don't see that you're ever initializing your Selenium object except for in Browser's setUp(String url) method. And that method is also not being called here.
You've also made your Browser's Selenium object public, so you don't need to declare another Selenium object in TestCase that's assigned by an accessor method -- you can just reference it from TestCase's Browser object.

Categories

Resources