I am currently working on trying to connect Selenium automation scripts to be run using Github action. I decided on using Gradle from how easy it looked to use when running these Selenium tests locally and in Github actions. I have been able to get these Selenium tests to work just fine locally using ./gradlew test
. I have also been writing all of this using Visual Studio Code.
Here is my gradle.yml:
name: Java CI with Gradle
on:
push:
branches: ["dev"]
pull_request:
branches: ["dev"]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 19
uses: actions/setup-java@v3
with:
java-version: "19"
distribution: "temurin"
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean test
Here is my build.gradle file:
/*
* This file was generated by the Gradle 'init' task.
*
* This is a general purpose Gradle build.
* Learn more about Gradle by exploring our samples at https://docs.gradle.org/8.0.1/samples
* This project uses @Incubating APIs which are subject to change.
*/
plugins {
id 'java'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'junit:junit:4.13'
implementation 'org.seleniumhq.selenium:selenium-java:4.1.1'
testImplementation("io.github.bonigarcia:webdrivermanager:5.3.2")
}
settings.gradle file:
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/8.0.1/userguide/multi_project_builds.html
* This project uses @Incubating APIs which are subject to change.
*/
plugins {
id("com.gradle.enterprise") version("3.9")
}
gradleEnterprise {
if (System.getenv("CI") != null) {
buildScan {
publishAlways()
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
}
}
}
rootProject.name = 'it-mendix-ci-kaizen-events'
And my Selenium java file:
import org.junit.*;
import java.util.concurrent.TimeUnit;
import java.lang.Thread;
import java.io.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Alert;
import org.openqa.selenium.Keys;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.WindowType;
import io.github.bonigarcia.wdm.WebDriverManager;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsNot.not;
public class CIHomePage {
private WebDriver driver;
@BeforeClass
public static void setupWebdriverChromeDriver() {
WebDriverManager.chromedriver().setup();
}
@Before
public void setup() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200","--ignore-certificate-errors","--disable-extensions","--no-sandbox","--disable-dev-shm-usage");
driver = new ChromeDriver(options);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
@After
public void teardown() {
if (driver != null) {
driver.quit();
}
}
@Test
public void homePageTitle() throws InterruptedException{
WebDriverWait wait = new WebDriverWait (driver, 45);
driver.get("https://notarealurl.com");
driver.findElement(By.id("Ecom_Password")).sendKeys("notarealpassword");
driver.findElement(By.id("Ecom_User_ID")).sendKeys("notarealusername");
driver.findElement(By.id("loginButton2")).click();
wait.until(ExpectedConditions.titleIs("Continuous Improvement - Event Name Overview"));
}
}
When these test run in Github actions I receive this error.
Exception
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for title to be "Continuous Improvement - Event Name Overview". Current title: "Access Manager" (tried for 45 second(s) with 500 milliseconds interval)
Build info: version: '4.1.1', revision: 'e8fcc2cecf'
System info: host: 'fv-az1028-100', ip: '10.1.0.192', os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.0-1033-azure', java.version: '19.0.2'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 110.0.5481.177, chrome: {chromedriverVersion: 110.0.5481.77 (65ed616c6e8e..., userDataDir: /tmp/.com.google.Chrome.Mh8RwC}, goog:chromeOptions: {debuggerAddress: localhost:42651}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), se:cdp: ws://localhost:42651/devtoo..., se:cdpVersion: 110.0.5481.177, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: ca87e954431ab0747fceab555c07e562
From what I can tell, the error keeps happening when Selenium is trying to log into SSO and can’t get past this page to be directed to the site that I am working on. I have been able to get this to work just fine locally on my machine. This also is not an issue when Selenium isn’t directed to log into our SSO. I have been able to get the scripts to work just fine when directing to a site without our SSO.
I am not sure if it is an issue with how I set up my gradle.yml file or need to do something different with how I wrote the Selenium test file.
2
Answers
Solved the issue, it was because logging into our SSO it requires a two-factor authentication so the server was unable to login after receiving the information.
Seems the line of code is a little off. A quick demonstration:
Code block:
Console Output:
This usecase
Accordingly, your line of code should be: