A Comprehensive Guide to Authentication Flow Testing with Selenium and Yenlo Connext Platform
Selenium is a popular open-source automated testing framework that is widely used for testing web applications. It enables testers to write and execute test cases in a wide range of programming languages, including Java, Python, Ruby, and C#. One of the key benefits of Selenium is its ability to simulate real user interactions with a web application, making it a valuable tool for testing the authentication process of web applications.
Authentication is the process of verifying the identity of a user, which can be done through different methods such as username and password, OAuth/OIDC, and Single Sign-On (SSO). With Selenium, testers can automate the process of login in and out of web applications, testing the functionality and security of the authentication process. Authentication process is a critical component of any web application, as it ensures that only authorized users have access to sensitive information and resources. Testing this process is an essential part of the development process and requires a comprehensive understanding of the various technologies and protocols involved.
In this blog, we will discuss how you can easily create a test suite to test the login flow for your applications.
I will use the Yenlo Connext platform as the Identity Provider to provide us with the authentication service. Yenlo Connext is a 24/7 hosted and managed cloud solution based on WSO2 technology.
Please note, this selenium testing will be able to test out the authentication when there is no multi factor authentication like Email OTP/ SMS OTP is enabled. Selenium official page also recommends testing out basic authentication without multi factor authentication.
How to set up a testing environment for web application authentication testing?
The first step in testing the authentication process of a web application is to set up the testing environment. This typically involves installing Selenium, as well as any additional software or libraries needed to interact with the web application. It is also important to have a clear understanding of the authentication process and the various steps involved, as well as the data that will be required to perform the tests.
For the scope of this blog, we will use an application which uses OIDC protocol for authentication with the identity provider in Connext platform. You can refer the official documentation of WSO2 on how to easily enable OIDC based authentication to your application. By using Yenlo Connext platform, you do not have to worry about all the nitty gritty of configurations, as it is a manged cloud service, that will handle the heavy load for you. I will not explain the OIDC flow here since our focus is more on testing the authentication process in this blog.
I will create a maven project for writing our test suite. Below is a sample maven pom file with necessary dependencies and plugins.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ConnextSeleniumTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ConnextSeleniumTest</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.7.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
Required Dependencies and Plugins for Automated Web Testing with Selenium and TestNG
Main dependencies:
- Selenium-java: This is a java language binding for the Selenium WebDriver, which is a popular open-source tool for automating web browsers. The selenium-java component provides a convenient way to interact with web browsers from a Java program, allowing developers to write automated tests, scrape data, or perform other automated tasks on the web easily.
- TestNG: It is a testing framework used in the development of Java applications. It provides a comprehensive testing framework that makes it easier to write, manage, and run tests for Java applications, improving the quality of the software and the efficiency of the testing process.
Plugins:
- Maven-surefire-plugin: It is a plugin in Apache Maven that is used to execute tests and generate reports. This plugin is typically used to execute tests written in Java with the JUnit or TestNG testing frameworks. The maven surefire plugin provides reports in different formats, such as plain text, XML, and HTML. The reports provide information about the test results, such as the number of tests executed, passed, and failed, and the details of the test cases. The reports also help to identify which tests have failed and provide information that can be used to debug and fix the tests.
Once the testing environment is set up, the next step is to write test cases that will simulate different scenarios and user interactions with the web application. This may involve creating test cases that verify that users are able to successfully log in and access their account, as well as test cases that verify that users are unable to access their account if they provide incorrect login credentials.
Following image shows the basic package structure I have used.
Setting up Test Environment in Selenium with TestNG’s @BeforeMethod and @AfterMethod Annotations
Before writing testcases, we should implement a method to setup test environment. TestNG provides @BeforeMethod annotation to execute certain methods before each test method in a test class. See the following example:
@BeforeMethod
public void setUp() {
ChromeOptions chromeOptions = new ChromeOptions();
//To run in headless mode
chromeOptions.addArguments(Constants.HEADLESS_MODE);
driver = new ChromeDriver(chromeOptions);
js = (JavascriptExecutor) driver;
driver.get(Constants.URL);
System.out.println("Visiting the CCP portal and redirected to login page");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Constants.IMPLICIT_WAIT, Constants.TIME_UNIT);
}
In this method, we can initialize the selenium web driver. Since I am going to run my tests against the chrome browser, I initialised it with Chrome driver. You can use any driver you want to test against.
I used the headless mode for running tests as it is faster & more efficient and would not popup a browser each time a test is executed. It is useful if you are running your tests in a server which only supports headless mode. To achieve headless mode, you can use ChromeOptions and set it.
The driver.get () method in Selenium is used to open a web page in the browser. It takes a URL as an argument and navigates the browser to that URL. The method waits until the page is fully loaded and returns control back to the test script. Once the page is loaded, the test script can perform various actions on the page, such as clicking buttons, filling forms, etc. The URL I have used here, is the URL of the authentication endpoint of the Yenlo Connext platform.
Example: https://<hostname-connext-idp>/oauth2/authorize?response_type=code&client_id=<client-id-of-the-application>&redirect_uri=<URL-of-the-application>
If the loading of elements of your page varies, it is wise to set driver.manage().timeouts().implicitlyWait() method. You can set the amount of time the driver will wait for an element to be present on the page before throwing an error. It applies to all elements in the scope of the WebDriver instance, so if the driver cannot find the desired element immediately, it will continue searching for it during the specified time interval. Since some of the elements in my application take time to load, I set the implicit wait time for 30 seconds.
In a similar fashion, we also need to have a method that will run after every test case to clean up test data, test environment or other common test clean-up tasks.
Example:
@AfterMethod
public void tearDown() {
driver.quit();
}
Sample Test Cases to Verify Successful and Unsuccessful User Login in Yenlo Connext Platform
Now, we can start writing our test cases. Below are two sample test cases to test. First one simulates a successful user login and verify that users can successfully log in. And the second test case simulates an unsuccessful login and verify that users are unable to access their account if they provide incorrect login credentials.
@Test (priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
@Test (priority = 2)
private void testIncorrectUsername(){
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.INCORRECT_USER_NAME,Constants.PASSWORD);
redirectingToErrorMessage();
}
To mark a method as a test case you need to use @Test annotation in TestNG. Then to specify the order of test execution you can use āpriorityā attribute. The lowest number will execute first.
Sample Test Cases for Testing Security Features and UI Functionality of Login Pages
In addition to these basic test cases, it is also important to test the various security features that are typically used in web applications to protect user data and prevent unauthorized access. This may include testing that users are prompted to change their password after a specified period, or whether the passwords field are masked. And you can test for SSO behaviour of your applications.
In addition to the login related flows, you can also test basic UI features are functioning properly for your login pages, or whether the necessary logo images are in place.
Following is a sample test case which checks for broken images in the login page.
@Test(priority = 3)
private void testBrokenImages(){
ccpLoginPage = new CCPLoginPage(driver);
int brokenImagesCount = 0;
List<WebElement> imageList = ccpLoginPage.images;
System.out.println("The page under test has " + imageList.size() + " images.");
for (WebElement image : imageList) {
if (image != null) {
String imagePath = image.getAttribute("src");
if (!isImageAvailable(imagePath)) {
brokenImagesCount++;
System.out.println(image.getAttribute("outerHTML") + " is broken.");
} else {
System.out.println("Image at " + image.getAttribute("outerHTML") + " is available");
}
}
}
System.out.println("The Connext Login page"+ " has " + brokenImagesCount + " broken images");
}
private boolean isImageAvailable(String imagePath) {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(imagePath);
try {
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
/* For valid images, the HttpStatus will be 200 */
if (responseCode != 200) {
return false;
} else {
return true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
To check if the images are available, we need to do a HTTP GET call to the image path. Therefore, we need to add the āhttpclientā dependency to our maven project.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
Sample Test Cases for Encryption and SSO Features
Following is a sample test case which checks whether the password field is masked.
@Test(priority = 4)
public void testPasswordEncryption() {
ccpLoginPage = new CCPLoginPage(driver);
WebElement passwordElement = ccpLoginPage.getPasswordElement();
boolean isEncrypted = passwordElement.getAttribute("type").equals("password");
Assert.assertEquals(isEncrypted, true, "Password field is not masked.");
}
Following is a sample test case which test out the SSO feature.
@Test(priority = 5)
public void testSSO() throws AWTException {
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
//Use a url of an application that is SSOed with the CCP portal
switchToNewTab("https://test-portal.com/ssoapplication/dashboard");
}
private void switchToNewTab(String url) {
String currentHandle = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open()");
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
if (!handle.equalsIgnoreCase(currentHandle)) {
driver.switchTo().window(handle);
driver.get(url);
landingToSSOApplication();
}
}
}
private void landingToApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/application/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
private void landingToSSOApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/ssoapplication/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
āswitchToNewTabā method take care of opening another browser tab, within same browser session, and load another application that is SSO ed with the earlier application.
ālandingToApplicationā method, verifies whether the user is logged in to the application.
ālandingToSSOApplicationā method, verifies whether the user is logged in to the other SSO application.
Don’t stop here! Bonus Selenium Test Cases Classe Included is awaiting you at the end of this blog.
Using POM and Page Factory class for testing authentication process
One of the challenges of testing the authentication process is that it often requires interaction with multiple pages, elements, and forms within the web application. To make this process easier and more efficient, many testers choose to use the Page Object Model (POM) design pattern, along with the Page Factory class, which is built into the Selenium framework. The POM pattern allows testers to encapsulate the details of interacting with the various elements of a page into reusable objects that can be easily referenced from multiple test cases.
The Page Factory class is a powerful tool for implementing the POM pattern, as it allows testers to define the elements of a page using annotations, and then easily reference those elements from their test cases. For example, a login page might have a username text box, a password text box, and a submit button. The Page Factory class makes it easy to define these elements in a single class, and then reference them from multiple test cases.
If you follow through our test cases, you can see references to classes called āCCPLoginPageā and āCCPHomePageā
Example:
@Test(priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
Those two classes are the āpage factory classesā representing the Login page and the application home page, respectively.
You can use the @FindBy annotation in a class attributes, and convert it to a Page Factory class in Selenium
Refer the example for marking username, password, and login button fields in CCPLoginPage Page Factory class.
public class CCPLoginPage {
private WebDriver driver;
@FindBy(id="username")
WebElement usernameElement;
@FindBy(id="password")
WebElement passwordElement;
@FindBy(css=".wr-btn")
WebElement loginButtonElement;
public CCPLoginPage (WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
The above class maps to following UI elements in login page.
<inputid=”username” name=”username” type=”text” class=”form-control” tabindex=”0″ placeholder=”Username” required autofocus>
<inputid=”password” name=”password” type=”password” class=”form-control” placeholder=”Password” autocomplete=”off”>
<button class=”wr-btn grey-bg col-xs-12 col-md-12 col-lg-12 margin-bottom-double” type=”submit”> Login </button>
For this class to work as a Page Factory object, you need to call PageFactory.initElements() within the constructor.
Then you can write methods within that class, which will set the values to those elements and then submit the information. The full source for CCPLoginPage and CCPHomePage can be found in Bonus section at the end of this blog.
Assertions in Selenium Test Cases
Assertions are used to validate the expected behaviour of a software application during testing. They are a key component of automated testing and help ensure that the application is functioning correctly. An assertion checks a specific condition, and if the condition is not met, the assertion fails, throwing an exception and marking the test case as failed. Some commonly used assertions in Selenium and other testing frameworks include:
- assertEquals: This assertion checks if two values are equal and throws an exception if they are not.
- assertTrue: This assertion checks if a condition is true, and throws an exception if it is false.
- assertFalse: This assertion checks if a condition is false, and throws an exception if it is true.
- assertNull: This assertion checks if a value is null, and throws an exception if it is not.
- assertNotNull: This assertion checks if a value is not null, and throws an exception if it is.
These assertions are used in conjunction with testing frameworks like TestNG, JUnit, etc. to validate the behaviour of the software application under test.
In our test cases we have done the following assertions:
Login to application:
- Assert login page title
- Assert application page title after login into the application
- Assert application URL after login into the application
Incorrect username:
- Assert login page title
- Assert failed login message
Password masking:
- Assert password field is masked or not
SSO:
- Assert application URL, and title before SSO
- Assert application URL and title of the other SSO application, after SSO
Setting up TestNG framework for Test Execution
Now you can register your test class in the TestNG framework by adding following entry to your testng.xml
<suite name="Suite1" verbose="1" >
<test name="CCPLogin" >
<classes>
<class name="org.yenlo.sample.CCPLoginSeleniumTest" />
</classes>
</test>
</suite>
Then you can go to your project root and execute āmvn testā command to execute the tests.
Once test execution is completed you can visit the ātarget/surefire-reportsā folder and view different reports of the test execution.
Conclusion: Testing the Authentication Process of a Web Application
Finally, it is important to perform continuous testing of the authentication process as part of the development process. This may involve running automated tests on a regular basis, as well as manual testing to verify that the authentication process continues to function correctly as changes are made to the web application.
In conclusion, testing the authentication process of a web application is an important and complex task that requires a deep understanding of the various technologies and protocols involved, as well as a clear understanding of the authentication process itself. By using Selenium, along with the Page Object Model and Page Factory, testers can easily write and execute test cases that simulate real user interactions with the web application and verify that the authentication process is working correctly. By performing continuous testing as part of the development process, developers can ensure that the authentication process remains secure and functional as the web application evolves over time.
BONUS: Sample Selenium Test Cases Classe for Web Applications
- Selenium testcases class.
package org.yenlo.sample;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.*;
import org.yenlo.sample.pagefactory.CCPHomePage;
import org.yenlo.sample.pagefactory.CCPLoginPage;
import org.yenlo.sample.pagefactory.util.Constants;
import java.awt.*;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Set;
public class CCPLoginSeleniumTest {
private WebDriver driver;
JavascriptExecutor js;
//Login page element repository
CCPLoginPage ccpLoginPage;
CCPHomePage ccpHomePage;
@BeforeMethod
public void setUp() {
ChromeOptions chromeOptions = new ChromeOptions();
//To run in headless mode
chromeOptions.addArguments(Constants.HEADLESS_MODE);
driver = new ChromeDriver(chromeOptions);
js = (JavascriptExecutor) driver;
driver.get(Constants.URL);
System.out.println("Visiting the CCP portal and redirected to login page");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Constants.IMPLICIT_WAIT, Constants.TIME_UNIT);
}
@AfterMethod
public void tearDown() {
driver.quit();
}
@Test(priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
@Test(priority = 2)
private void testIncorrectUsername(){
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.INCORRECT_USER_NAME, Constants.PASSWORD);
redirectingToErrorMessage();
}
@Test(priority = 3)
private void testBrokenImages(){
ccpLoginPage = new CCPLoginPage(driver);
int brokenImagesCount = 0;
List<WebElement> imageList = ccpLoginPage.images;
System.out.println("The page under test has " + imageList.size() + " images.");
for (WebElement image : imageList) {
if (image != null) {
String imagePath = image.getAttribute("src");
if (!isImageAvailable(imagePath)) {
brokenImagesCount++;
System.out.println(image.getAttribute("outerHTML") + " is broken.");
} else {
System.out.println("Image at " + image.getAttribute("outerHTML") + " is available");
}
}
}
System.out.println("The Connext Login page"+ " has " + brokenImagesCount + " broken images");
}
@Test(priority = 4)
public void testPasswordEncryption() {
ccpLoginPage = new CCPLoginPage(driver);
WebElement passwordElement = ccpLoginPage.getPasswordElement();
boolean isEncrypted = passwordElement.getAttribute("type").equals("password");
Assert.assertEquals(isEncrypted, true, "Password field is not masked.");
}
@Test(priority = 5)
public void testSSO() throws AWTException {
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
//Use a url of an application that is SSOed with the CCP portal
switchToNewTab(" https://test-portal.com/ssoapplication/dashboard ");
}
private void switchToNewTab(String url) {
String currentHandle = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open()");
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
if (!handle.equalsIgnoreCase(currentHandle)) {
driver.switchTo().window(handle);
driver.get(url);
landingToSSOApplication();
}
}
}
/**
* Verify login page title.
*/
private void assertPageTitle() {
String loginPageTitle = driver.getTitle();
String expectedLoginPageTitle = "Connext Identity Server";
Assert.assertEquals(loginPageTitle, expectedLoginPageTitle, "Connext login page title doesn't match");
}
private void landingToApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/application/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
/**
* Method to load the application that is in SSO with the CCP portal.
* Here I have used the same CCP portal. But you can update the method to use a different application URL.
*/
private void landingToSSOApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl=" https://test-portal.com/ssoapplication/dashboard ";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
private void redirectingToErrorMessage(){
ccpLoginPage.waitUntilErrorMessageLoads();
assertFailedLoginMessage();
}
private void assertFailedLoginMessage(){
String errorNotification = ccpLoginPage.getFailedLoginMessage();
String expectedErrorNotification = "Login failed! Please recheck the username and password and try again.";
Assert.assertEquals(errorNotification,expectedErrorNotification,"Expected error message is not matching");
}
private boolean isImageAvailable(String imagePath) {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(imagePath);
try {
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
/* For valid images, the HttpStatus will be 200 */
if (responseCode != 200) {
return false;
} else {
return true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2. CCPLoginPage & CCPHomePage Page Factory Classes.
package org.yenlo.sample.pagefactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
public class CCPLoginPage {
private WebDriver driver;
@FindBy(id="username")
WebElement usernameElement;
@FindBy(id="password")
WebElement passwordElement;
@FindBy(css=".wr-btn")
WebElement loginButtonElement;
@FindBy(className = "alert-danger")
WebElement failedLoginNotificationElement;
@FindBy(tagName = "img")
public List<WebElement> images;
String failedLoginNotificationClassName = "alert-danger";
public CCPLoginPage(WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
//Set username in username text box
public void setUsername(String username){
usernameElement.clear();
usernameElement.sendKeys(username);
System.out.println("Entering the username");
}
//Set password in password text box
public void setPassword(String password){
passwordElement.clear();
passwordElement.sendKeys(password);
System.out.println("entering the password");
}
//Submit username & password
public void clickLogin(){
loginButtonElement.click();
System.out.println("Clicking login button");
}
/**
* Method to call from the testcase, to login a user
*/
public void loginToCCP(String username, String password){
//fill username
this.setUsername(username);
//fill password
this.setPassword(password);
//click login button
this.clickLogin();
}
public void waitUntilErrorMessageLoads(){
WebDriverWait wdw = new WebDriverWait(driver, Duration.ofSeconds(30)); // wait up to 30 seconds
wdw.until(ExpectedConditions.visibilityOfElementLocated(By.className(failedLoginNotificationClassName)));
}
public String getFailedLoginMessage(){
return failedLoginNotificationElement.getText();
}
public WebElement getPasswordElement(){
return passwordElement;
}
}
package org.yenlo.sample.pagefactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
/**
* CCP home page web element repository
*/
public class CCPHomePage {
private WebDriver driver;
String ccpHomePageElementXpath = "//span[text()='Dashboard']";
public CCPHomePage(WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
/**
* Method to wait until CCP home page loads after login.
*/
public void waitUntilHomePageLoads(){
WebDriverWait wdw = new WebDriverWait(driver, Duration.ofSeconds(30)); // wait up to 30 seconds
wdw.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(ccpHomePageElementXpath)));
}
}