Jump to content
Changes to the Jaspersoft community edition download ×

sadakar

Members
  • Posts

    343
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

sadakar's Achievements

  1. The following worked for me with the dependencies mentioned in pom.xml If you are on 7.8.0 TestNG downgrade it to 7.7.0 or do not take testng dependency rather take cucumber-testng and cucumber-java both versioned 7.12.0 Eclipse console log:[RemoteTestNG] detected TestNG version 7.8.0SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Defaulting to no-operation (NOP) logger implementationSLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.java.lang.NoSuchMethodError: 'void org.testng.TestRunner.<init>(org.testng.internal.IConfiguration, org.testng.ISuite, org.testng.xml.XmlTest, boolean, java.util.Collection, java.util.List)' at org.testng.remote.support.RemoteTestNG6_12$1.newTestRunner(RemoteTestNG6_12.java:33) at org.testng.remote.support.RemoteTestNG6_12$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG6_12.java:66) at org.testng.ITestRunnerFactory.newTestRunner(ITestRunnerFactory.java:52) at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:720) at org.testng.SuiteRunner.init(SuiteRunner.java:224) at org.testng.SuiteRunner.<init>(SuiteRunner.java:116) at org.testng.TestNG.createSuiteRunner(TestNG.java:1375) at org.testng.TestNG.createSuiteRunners(TestNG.java:1349) at org.testng.TestNG.runSuitesLocally(TestNG.java:1191) at org.testng.TestNG.runSuites(TestNG.java:1114) at org.testng.TestNG.run(TestNG.java:1082) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) pom.xml <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>CucumberParallelExecutionTestNG</groupId> <artifactId>CucumberParallelExecutionTestNG</artifactId> <version>0.0.1-SNAPSHOT</version> <name>CucumberParallelExecutionTestNG</name> <description>CucumberParallelExecutionTestNG</description> <dependencies> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.12.0</version> </dependency> <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>7.12.0</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.10.0</version> </dependency> <!-- Comment testng dependency since pom already has cucumber-testng or you could enable the dependency with downgraded version 7.7.0 --> <!-- https://mvnrepository.com/artifact/org.testng/testng --> <!-- <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.8.0</version> </dependency> --> <dependency> <groupId>tech.grasshopper</groupId> <artifactId>extentreports-cucumber7-adapter</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>runners.CucumberRunnerCLI</mainClass> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build></project>
  2. Hi, How can we remove blog sites in the Jaspersoft Planet ? I don't see "Feeds" section ( so can't edit or delete) in my account as explained here : https://community.jaspersoft.com/wiki/planet-jaspersoft-help-guide. Someone from Jaspersoft has added my blog site few years ago and now I want this to be removed since the content I post is no longer for Jasper rather automation. https://community.jaspersoft.com/planet?f%5B0%5D=field_feed_source%3A841187 Attached image. Please help.
  3. Hi, In this post, we can see how to use JVM shut down hook with in cucumber Hooks. What is JVM shut down hook ? (Definition credits : geeksforgeeks.org) A special construct that facilitates the developers to add some code that has to be run when the Java Virtual Machine (JVM) is shutting down is known as the Java shutdown hook. Begin with some interesting questions ! 1) Did you ever think of refreshing a folder in java coding to send latest run cucumber report or extent report ? 2) Did you keep your email notification code in cucumber After or AfterAll hook and tried sending email but ended-up with old report in mail inbox ? 3) How did you solve this problem with Cucumber, TestNG integration ? Perhaps! There might be other solutions and could be better ones. My approach was, effectively make use of JVM shut down hook with in cucumber AfterAll hook to have the latest run report attached and sent over the email. It started with, What is cucumber AfterAll hook ? AfterAll is a cucumber hook that run after all scenarios have been executed. @AfterAllpublic static void afterAll() { // Runs after all scenarios}JVM Shutdown hook basic example: In the below program, there are two print statements. By using addShutdownHook JVM would print "This text prints before shutdown!" firstly and at the time JVM shut down it prints "Shutdown Hook is running and this prints at last!" That is, statements inside run() method executes at the very end. public class ShutDownHook{ public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { System.out.println("Shutdown Hook is running and this prints at last!"); } }); System.out.println("This text prints before shutdown!"); }}Below is the combined implementation of @AfterAll cucumber hook and JVM addShutdownHook. In the run() method, keep the email triggering code so the selenium execution always picks the latest report to be sent in the mail. It pretty much worked through jar execution too. package parallel;import java.net.InetAddress;import java.net.UnknownHostException;import io.cucumber.java.After;import io.cucumber.java.AfterAll;import io.cucumber.java.Before;import io.cucumber.java.Scenario;public class Hooks { @Before(order = 0) public void before(Scenario scenaio) throws Exception { DriverFactory.setDriver(); System.out.println("Current Thread Name:" + Thread.currentThread().getName()); System.out.println("Current Thread ID:" + Thread.currentThread().getId()); } @After(order = 0) public void after() throws Exception { DriverFactory.closeDriver(); } @AfterAll(order = 0) public static void afterAll() throws UnknownHostException { System.out.println("AfterAll - with order=0"); InetAddress localhost = InetAddress.getLocalHost(); System.out.println("System IP Address : " + (localhost.getHostAddress()).trim()); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { System.out.println("Shutdown Hook is running and this text prints before JVM shut downs!"); } })); System.out.println("This text prints before Shutdown hook"); }} Eclipse logs: [RemoteTestNG] detected TestNG version 7.7.0SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Defaulting to no-operation (NOP) logger implementationSLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.@LoginFeature @ForgotPasswordScenario: Forgot password link verification # parallel/Login.feature:16@LoginFeature @LoginScenario: Login to Orange HRM # parallel/Login.feature:9Jun 11, 2023 1:01:23 AM org.openqa.selenium.remote.service.DriverService$Builder getLogOutputINFO: Driver logs no longer sent to console by default; https://www.selenium.dev/documentation/webdriver/drivers/service/#setting-log-outputJun 11, 2023 1:01:23 AM org.openqa.selenium.remote.service.DriverService$Builder getLogOutputINFO: Driver logs no longer sent to console by default; https://www.selenium.dev/documentation/webdriver/drivers/service/#setting-log-outputCurrent Thread Name:TestNG-PoolService-0Current Thread ID:16Current Thread Name:TestNG-PoolService-1Current Thread ID:17 Given User is on login page # parallel.LoginStepDef.user_is_on_login_page() When User enters username "Admin" # parallel.LoginStepDef.user_enters_username(java.lang.String) Given User is on login page # parallel.LoginStepDef.user_is_on_login_page() Then User verifies Forgot password link display # parallel.LoginStepDef.user_verifies_forgot_password_link_display() And User enters password "Admin123" # parallel.LoginStepDef.user_enters_password(java.lang.String) And User clicks on Login button # parallel.LoginStepDef.user_clicks_on_login_button()Navigation to home page Then User should navigate to Orange HRM home page # parallel.LoginStepDef.user_should_navigate_to_orange_hrm_home_page()AfterAll - with order=0System IP Address : 192.168.1.8This text prints before Shutdown hook┌──────────────────────────────────────────────────────────────────────────┐│ View your Cucumber Report at: ││ https://reports.cucumber.io/reports/213e45d0-8053-4753-b2c4-78f40d98bd71 ││ ││ This report will self-destruct in 24h. ││ Keep reports forever: https://reports.cucumber.io/profile │└──────────────────────────────────────────────────────────────────────────┘PASSED: io.cucumber.testng.AbstractTestNGCucumberTests.runScenario("Login to Orange HRM", "Login page validations") Runs Cucumber ScenariosPASSED: io.cucumber.testng.AbstractTestNGCucumberTests.runScenario("Forgot password link verification", "Login page validations") Runs Cucumber Scenarios=============================================== Default test Tests run: 1, Failures: 0, Skips: 0==============================================================================================Default suiteTotal tests run: 2, Passes: 2, Failures: 0, Skips: 0===============================================Shutdown Hook is running and this text prints before JVM shut downs! I hope this helped you a bit! If you like it, please do Subscribe my YouTube channel for interesting updates.
  4. Hi, In this post, we will see how to run cucumber scenarios in parallel with TestNG. What is parallel testing in cucumber? Parallel testing in Cucumber refers to the ability to execute Cucumber scenarios in parallel, allowing multiple scenarios to run simultaneously and speeding up the overall test execution time. Consider below factors while implementing parallel execution. Scenario IndependenceThread SafetyTagging ScenariosSynchronizationSoftware : Java : "17.0.7" 2023-04-18 LTS (java -version) Maven : Apache Maven 3.9.2 (mvn -version) Chrome browser: 114.0.5735.110 (Official Build) (64-bit)Chrome WebDriver: 114.0.5735.90 https://chromedriver.storage.googleapis.com/index.html?path=114.0.5735.90/ cucumber-java 7.12.0 cucumber-testng 7.12.0 selenium-java 4.10.0 maven-surefire-plugin 3.1.2 maven-compiler-plugin 3.11.0 Example: Execute two scenarios in parallel from a single feature file. i.e., 1) Verify user is able to login to the application with valid credentials 2) Verify Forgot password link is displayed on login page. Is it necessary to have testng.xml for parallel execution ? There could be different approaches to perform parallel execution from command line or jar file or from CI/CD method, in this demo I'd say yes it is necessary to have testng.xml so that we can pass dynamic thread count. What is ThreadLocal webdriver in cucumber ? Why it is important ? A ThreadLocal webdriver refers to an instance of a WebDriver object that is stored in a ThreadLocal variable. Each thread running a Cucumber scenario or step can have its own WebDriver instance, isolated from other threads.This approach ensures thread safety and prevents conflicts when executing scenarios in parallel. Here's why ThreadLocal webdriver is important Thread SafetyParallel ExecutionResource ManagementScenario IsolationThe project folder structure: Is mandatory to keep all the code in "parallel" folder as in many example over the internet ? No, it is not necessary to keep them in "parallel" folder. Similarly to keep the features NO "parallel" folder is required. Concepts covered in code base: DriverFactory for chrome and edge - How to pass chrome or edge as command line argument ? Parallel execution configurations - Where and how to configure parallel execution with TestNG? POM model with page factory pattern - How to isolate locators and step definitions ? Cucumber hooks - What is the recommendation of cucumber hooks over TestNG hooks ? Reports Which report is to be used - cucumber reports or extent reports ? cucumber reports Where to write email code to send the latest reports ? In JVM shutdown hook that is written in cucumber AfterAll hook(Did you ever try to remove or refresh a folder to have the latest reports to be sent over email) How to run the project ?Through command line Through eclipse run as TestNGThrough executable jar fileWould you like to watch few mins demo in a no voice video ? Jumping on to the core of this article i.e., parallel testing Parallel execution configurations: (For complete code download project from GitHub or Use this link to download as Zip) Declare thread local driver in WebDriverFactory java class and then set, get and remove instances of the driver. private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); Override the DataProvider annotation with parallel=true in CucumberRunnerTest that extends AbstractTestNGCucumberTests class. public class CucumberRunnerTest extends AbstractTestNGCucumberTests { @Override @DataProvider(parallel = true) public Object[][] scenarios() { return super.scenarios(); } } Create a testng.xml file and give parallel=true and data-provider-thread-count=1 and the runner class as shown below. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="Suite" parallel="true" data-provider-thread-count="1" verbose="2"> <test name="Test"> <classes> <class name="runners.CucumberRunnerTest" /> </classes> </test> <!-- Test --> </suite> <!-- Suite --> In pom.xml add the testng.xml as suiteXml file in maven-surefire-plugin. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> That's all we need to make cucumber scenarios to run parallel with TestNG as testing framework. So, after configurations - How to run the code to see parallel execution ? On the command prompt - maven execution Navigate to the the project folder location - you should have the pom.xml in it. Run below command in Command prompt. mvn -Dbrowser=chrome -Ddataproviderthreadcount=2 test This command opens two chrome browser parallelly as passing dataproviderthreadcount =2 If passed 1 then sequential execution takes place. On the command prompt - jar execution Use the maven-assembly-plugin and Main.run method creation technique to create a jar file (scroll down to the complete code section below and see how assembly plugin is configured in pom.xml and how Main.main takes arguments in CucumberRunnerCLI.java class ) Now to create executable/runnable jar file give below goal in eclipse (Runs As -> Maven build -> Goals) (Note: Make sure to clean the project prior assembling) clean package assembly:single -Dmaven.test.skip=true Running above command downloads required jar files in .m2 repository and creates and copy the jar file in target folder. [ [1;34mINFO [m] Building jar: E:\Automation\CucumberParallelExecutionTestNG\target\CucumberParallelExecutionTestNG-0.0.1-SNAPSHOT-jar-with-dependencies.jar [ [1;34mINFO [m] [1m------------------------------------------------------------------------ [m [ [1;34mINFO [m] [1;32mBUILD SUCCESS Use below command to run the scenarios from jar generated in target folder. java -Ddataproviderthreadcount=1 -Dbrowser=chrome -jar CucumberParallelExecutionTestNG-0.0.1-SNAPSHOT-jar-with-dependencies.jar In the Eclipse Run As TestNG with Run Configurations Run As -> TestNG -> Run Configurations -> VM Arguments --> -Dbrowser=chrome -Ddataproviderthreadcount=2 This is how one could able to run the scenarios in parallel with TestNG as the testing framework. Interesting Research Observations: Over the internet there are bunch of suggestions with maven sure fire plugin to play with parallel=method, threadCount=3 and incase of maven fail safe plugin to play with dataproviderthreadcount and value in the properties those didn't work for me at least. i.e., None of the below configurations worked to run scenarios parallel. maven-surefire-plugin with parallel=true and threadCount=3 DID NOT work<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <parallel>methods</parallel> <threadCount>3</threadCount> <perCoreThreadCount>false</perCoreThreadCount> <useUnlimitedThreads>false</useUnlimitedThreads> </configuration> </plugin> maven-failsafe-plugin with dataproviderthreadcount property with value DID NOT work. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.22.0</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <properties> <property> <name>dataproviderthreadcount</name> <value>2</value> </property> </properties> </configuration> </execution> </executions> </plugin> ---------------------------------------------------------------------------------------------------------- Code base: Login.feature#Author: Sadakar Pochampalli@LoginFeatureFeature: Login page validations Background: Given User is on login page @Login Scenario: Login to Orange HRM When User enters username "Admin" And User enters password "admin123" And User clicks on Login button Then User should navigate to Orange HRM home page @ForgotPassword Scenario: Forgot password link verification Then User verifies Forgot password link display pom.xml <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>CucumberParallelExecutionTestNG</groupId> <artifactId>CucumberParallelExecutionTestNG</artifactId> <version>0.0.1-SNAPSHOT</version> <name>CucumberParallelExecutionTestNG</name> <description>CucumberParallelExecutionTestNG</description> <dependencies> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.12.0</version> </dependency> <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>7.12.0</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.10.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.testng/testng --> <!-- <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.8.0</version> </dependency>--> <dependency> <groupId>tech.grasshopper</groupId> <artifactId>extentreports-cucumber7-adapter</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>runners.CucumberRunnerCLI</mainClass> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build></project>testng.xml <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"><suite name="Suite" parallel="true" data-provider-thread-count="1" verbose="2"> <test name="Test"> <classes> <class name="runners.CucumberRunnerTest" /> </classes> </test> <!-- Test --></suite> <!--Suite -->WebDriverFactory.java package driverfactory;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.chrome.ChromeOptions;import org.openqa.selenium.edge.EdgeDriver;public final class WebDriverFactory { private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); public static void setDriver() { String browser = System.getProperty("browser", "chrome"); if (browser.equalsIgnoreCase("chrome")) { System.setProperty("webdriver.chrome.driver", "E:\\Drivers\\chromedriver.exe"); ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); driver.set(new ChromeDriver(options)); getDriver().manage().window().maximize(); getDriver().manage().deleteAllCookies(); } else if (browser.equalsIgnoreCase("edge")) { System.setProperty("webdriver.edge.driver", "E:\\Drivers\\msedgedriver.exe"); driver.set(new EdgeDriver()); getDriver().manage().window().maximize(); getDriver().manage().deleteAllCookies(); } } public static WebDriver getDriver() { return driver.get(); } public static void closeDriver() { driver.get().quit(); driver.remove(); }}Hooks.java package hooks;import java.net.InetAddress;import java.net.UnknownHostException;import driverfactory.WebDriverFactory;import io.cucumber.java.After;import io.cucumber.java.AfterAll;import io.cucumber.java.Before;import io.cucumber.java.Scenario;public class Hooks { @Before(order = 0) public void before(Scenario scenaio) throws Exception { WebDriverFactory.setDriver(); System.out.println("Current Thread Name:" + Thread.currentThread().getName()); System.out.println("Current Thread ID:" + Thread.currentThread().getId()); } @After(order = 0) public void after() throws Exception { WebDriverFactory.closeDriver(); } @AfterAll(order = 0) public static void afterAll() throws UnknownHostException { System.out.println("AfterAll - with order=0"); InetAddress localhost = InetAddress.getLocalHost(); System.out.println("System IP Address : " + (localhost.getHostAddress()).trim()); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { System.out.println("Write email code in this method - Shutdown Hook is running and this text prints before JVM shut downs!"); } })); System.out.println("This text prints before Shutdown hook"); }}LoginPageFactory.java package pagefactory;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.support.FindBy;public class LoginPageFactory { public WebDriver driver; public LoginPageFactory(WebDriver driver) { this.driver = driver; } // Username locator @FindBy(xpath = "//input[@name='username]") public WebElement userName; // Password locator @FindBy(xpath = "//input[@name=password]") public WebElement passWord; // Login button locator @FindBy(xpath = "//button[@type=submit]") public WebElement loginButton; // Forgot password locator @FindBy(xpath = "//p[@class=oxd-text oxd-text--p orangehrm-login-forgot-header]") public WebElement forgotPassword; // Method that performs Username action public void enterUsername(String uname) { userName.sendKeys(uname); } // Method that performs Password action public void enterPassword(String pwd) { passWord.sendKeys(pwd); } // Method that performs Login action public void clickLogin() { loginButton.click(); } // Method that performs Forgot Password link verification public boolean isForgotPasswordLinkPresent() { return forgotPassword.isDisplayed(); }}CucumberRunnerCLI.java package runners;import io.cucumber.core.cli.*;public class CucumberRunnerCLI { public static void main(String[] args) { String threadCount = System.getProperty("dataproviderthreadcount", "1"); Main.run(new String[] { "classpath:scenarios", "-g", "driverfactory", "-g","hooks", "-g","pagefactory", "-g","runners", "-g","stepdef", "-p","pretty", "-p","json:target/cucumber-reports/cucumber.json", "-p","html:target/cucumber-reports/cucumber-report.html", "-m", "--threads",threadCount }, Thread.currentThread().getContextClassLoader()); }}CucumberRunnerTest.java package runners;import org.testng.annotations.DataProvider;import io.cucumber.testng.AbstractTestNGCucumberTests;import io.cucumber.testng.CucumberOptions;@CucumberOptions( features = "classpath:scenarios", tags = "@Login or @ForgotPassword", glue = { "driverfactory", "hooks", "pagefactory", "runners", "stepdef" }, plugin = { "pretty","json:target/cucumber-reports/cucumber.json", "html:target/cucumber-reports/cucucmber-report.html" }, monochrome = true)public class CucumberRunnerTest extends AbstractTestNGCucumberTests { @Override @DataProvider(parallel = true) public Object[][] scenarios() { return super.scenarios(); }}LoginStepDef.java package stepdef;import org.openqa.selenium.support.PageFactory;import org.testng.Assert;import driverfactory.WebDriverFactory;import io.cucumber.java.en.Given;import io.cucumber.java.en.Then;import io.cucumber.java.en.When;import pagefactory.LoginPageFactory;public class LoginStepDef { LoginPageFactory login = PageFactory.initElements(WebDriverFactory.getDriver(), LoginPageFactory.class); @Given("User is on login page") public void user_is_on_login_page() throws InterruptedException { WebDriverFactory.getDriver().get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"); Thread.sleep(3000); } @When("User enters username {string}") public void user_enters_username(String username) { login.enterUsername(username); } @When("User enters password {string}") public void user_enters_password(String password) { login.enterPassword(password); } @When("User clicks on Login button") public void user_clicks_on_login_button() throws InterruptedException { login.clickLogin(); Thread.sleep(3000); } @Then("User should navigate to Orange HRM home page") public void user_should_navigate_to_orange_hrm_home_page() { String expectedURLToNavigate = "https://opensource-demo.orangehrmlive.com/web/index.php/dashboard/index"; String actualURLNavigated = WebDriverFactory.getDriver().getCurrentUrl(); Assert.assertEquals(actualURLNavigated, expectedURLToNavigate); } @Then("User verifies Forgot password link display") public void user_verifies_forgot_password_link_display() { Assert.assertTrue(login.isForgotPasswordLinkPresent()); }} cucumber.propertiescucumber.publish.enabled=true Take another look at the folder structure:I hope this helped you a bit ! If you liked it do subscribe my YouTube channel for interesting tech updates.
  5. https://chromedriver.storage.googleapis.com/index.html https://www.chromium.org/administrators/turning-off-auto-updates/
  6. While we were trying to run the automation code in AWS workspaces, we stuck with the following error message and the temporary solution was to add the following argument to the chrome browser. options.addArguments("--remote-debugging-port=9222"); The observation is that even after adding this argument, we have to make sure that the browser is NOT opened in the AWS instance. [RemoteTestNG] detected TestNG version 7.4.0SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Defaulting to no-operation (NOP) logger implementationSLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.Starting ChromeDriver 111.0.6615.69 (bd2a7bcb881c11e8cfe3078709382934e3916914-refs/branch-heads/5615@{#936}) on port 16598Only local connections are allowed.Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.ChromeDriver was started successfully.FAILED: testorg.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: unknown error: DevToolsActivePort file doesn't exist Host info: host: 'DESKTOP-', ip: '10.222.112.9'Build info: version: '4.9.0', revision: 'd7057100a6'System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.6'Driver info: org.openqa.selenium.chrome.ChromeDriverCommand: [null, newSession {capabilities=[Capabilities {acceptInsecureCerts: true, browserName: chrome, goog:chromeOptions: {args: [--remote-allow-origins=*, --ignore-certificate-errors, --disable-dev-shm-usage], extensions: []}}]}] at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:136) at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:94) at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:68) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:165) at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:183) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:158) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:543) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:229) at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:157) at org.openqa.selenium.chromium.ChromiumDriver.<init>(ChromiumDriver.java:101) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:88) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:84) at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:73) at com.test.Test2.test(Test2.java:22) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133) at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598) at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173) at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46) at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824) at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.testng.TestRunner.privateRun(TestRunner.java:794) at org.testng.TestRunner.run(TestRunner.java:596) at org.testng.SuiteRunner.runTest(SuiteRunner.java:377) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332) at org.testng.SuiteRunner.run(SuiteRunner.java:276) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212) at org.testng.TestNG.runSuitesLocally(TestNG.java:1134) at org.testng.TestNG.runSuites(TestNG.java:1063) at org.testng.TestNG.run(TestNG.java:1031) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)=============================================== Default test Tests run: 1, Failures: 1, Skips: 0==============================================================================================Default suiteTotal tests run: 1, Passes: 0, Failures: 1, Skips: 0===============================================
  7. For HTML-5 Stacked Percentage Bar Chart in Jaspersoft Design Studio How to get percentage on bars ? When there are two percentages, for instance 0 and 100 - how to hide 0 and display only 100% on bar ? How to maintain fixed width for bars ? Below image depicts how the visualization outputs before and after applying basic and advanced properties Tap on the image for better visibility. Below advanced properties makes the graph to look like on the right side graph 1) To get percentage on bars plotOptions.series.dataLabels.enabled = true 2) To get the percentage on bars with value 0 disabled and 100 having percentage symbol plotOptions.series.dataLabels.formatter="function(){ var val = this.y; if(val == 0){return '';} else return val+'%';}" The equivalent java script for this is as follows. function(){ var val = this.y; if(val == 0){ return ''; } else return val+'%';} 3) To fix the bar width give plotOptions.bar.pointWidth=30 (Tap on the image for better visibility) JRXML( Works on 7.9.0 Professional Studio or later) <?xml version="1.0" encoding="UTF-8"?><!-- Created with Jaspersoft Studio version 7.9.0.final using JasperReports Library version 6.16.0-48579d909b7943b64690c65c71e07e0b80981928 --><jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="HTML-5StackedPercentageBarChart.jrxml" pageWidth="1200" pageHeight="842" columnWidth="1160" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="831cc732-af9c-4611-9fda-cc7946b3ba40"> <property name="com.jaspersoft.studio.data.sql.tables" value=""/> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="foodmartVeeraTraining"/> <property name="ireport.jasperserver.url" value="http://localhost:8080/jasperserver-pro/"/> <property name="ireport.jasperserver.user" value="superuser"/> <property name="ireport.jasperserver.reportUnit" value="/Training2023/HTML_5StackedPercentageBarChart"/> <property name="ireport.jasperserver.report.resource" value="/Training2023/HTML_5StackedPercentageBarChart_files/main_jrxml"/> <property name="com.jaspersoft.studio.unit." value="pixel"/> <property name="com.jaspersoft.studio.unit.pageHeight" value="pixel"/> <property name="com.jaspersoft.studio.unit.pageWidth" value="pixel"/> <property name="com.jaspersoft.studio.unit.topMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.bottomMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.leftMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.rightMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.columnWidth" value="pixel"/> <property name="com.jaspersoft.studio.unit.columnSpacing" value="pixel"/> <queryString language="SQL"> <![CDATA[(select 'Cate10' as Category, 'Series1' as Series, 40 as SeriesValue limit 1)union all(select 'Cate10' as Category, 'Series2' as Series, 60 as SeriesValue limit 1)union all(select 'Cate9' as Category, 'Series1' as Series, 10 as SeriesValue limit 1)union all(select 'Cate9' as Category, 'Series2' as Series, 90 as SeriesValue limit 1)union all(select 'Cate8' as Category, 'Series1' as Series, 100 as SeriesValue limit 1)union all(select 'Cate8' as Category, 'Series2' as Series, 0 as SeriesValue limit 1)union all(select 'Cate7' as Category, 'Series1' as Series, 45 as SeriesValue limit 1)union all(select 'Cate7' as Category, 'Series2' as Series, 55 as SeriesValue limit 1)union all(select 'Cate6' as Category, 'Series1' as Series, 80 as SeriesValue limit 1)union all(select 'Cate6' as Category, 'Series2' as Series, 20 as SeriesValue limit 1)union all(select 'Cate5' as Category, 'Series1' as Series, 15 as SeriesValue limit 1)union all(select 'Cate5' as Category, 'Series2' as Series, 85 as SeriesValue limit 1)union all(select 'Cate4' as Category, 'Series1' as Series, 90 as SeriesValue limit 1)union all(select 'Cate4' as Category, 'Series2' as Series, 10 as SeriesValue limit 1)union all(select 'Cate3' as Category, 'Series1' as Series, 25 as SeriesValue limit 1)union all(select 'Cate3' as Category, 'Series2' as Series, 75 as SeriesValue limit 1)union all(select 'Cate2' as Category, 'Series1' as Series, 24 as SeriesValue limit 1)union all(select 'Cate2' as Category, 'Series2' as Series, 76 as SeriesValue limit 1)union all(select 'Cate1' as Category, 'Series1' as Series, 34 as SeriesValue limit 1)union all(select 'Cate1' as Category, 'Series2' as Series, 66 as SeriesValue limit 1)]]> </queryString> <field name="category" class="java.lang.String"> <property name="com.jaspersoft.studio.field.name" value="category"/> <property name="com.jaspersoft.studio.field.label" value="category"/> </field> <field name="series" class="java.lang.String"> <property name="com.jaspersoft.studio.field.name" value="series"/> <property name="com.jaspersoft.studio.field.label" value="series"/> </field> <field name="seriesvalue" class="java.lang.Integer"> <property name="com.jaspersoft.studio.field.name" value="seriesvalue"/> <property name="com.jaspersoft.studio.field.label" value="seriesvalue"/> </field> <background> <band splitType="Stretch"/> </background> <title> <band height="42" splitType="Stretch"> <textField> <reportElement x="20" y="0" width="480" height="42" uuid="c437fc8c-354e-4dfe-b263-ff16f0e2b68d"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="13" isBold="true"/> </textElement> <textFieldExpression><![CDATA["HTML-5 Stacked Percentage Bar Chart - Before Applying Adv. Properties"]]></textFieldExpression> </textField> <textField> <reportElement x="600" y="0" width="480" height="42" uuid="2f7f2d3a-5aa3-4d3b-8a88-77b097b3fdd7"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="13" isBold="true"/> </textElement> <textFieldExpression><![CDATA["HTML-5 Stacked Percentage Bar Chart - After Applying Adv. Properties"]]></textFieldExpression> </textField> </band> </title> <summary> <band height="460" splitType="Stretch"> <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.FreeLayout"/> <property name="com.jaspersoft.studio.unit.height" value="px"/> <componentElement> <reportElement x="600" y="0" width="480" height="460" uuid="31617bd0-29e7-494e-a309-e82ff9a918e9"/> <hc:chart xmlns:hc="http://jaspersoft.com/highcharts" xsi:schemaLocation="http://jaspersoft.com/highcharts http://jaspersoft.com/schema/highcharts.xsd" type="StackedPercentBar"> <hc:chartSetting name="default"> <hc:chartProperty name="title.text" value=""/> <hc:chartProperty name="credits.enabled" value="false"/> <hc:chartProperty name="credits.href" value=""/> <hc:chartProperty name="credits.text" value=""/> <hc:chartProperty name="yAxis.title.text" value=""/> <hc:chartProperty name="chart.zoomType" value="xy"/> <hc:chartProperty name="colors_customSimpleMode" value="true"/> <hc:chartProperty name="colors"> <hc:propertyExpression><![CDATA[Arrays.asList("#009A17","#D64550","#90ed7d","#f7a35c","#8085e9","#f15c80","#e4d354","#2b908f","#f45b5b","#91e8e1")]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="plotOptions.series.dataLabels.enabled_customSimpleMode" value="true"/> <hc:chartProperty name="plotOptions.series.dataLabels.enabled"> <hc:propertyExpression><![CDATA[true]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="plotOptions.bar.pointWidth_customSimpleMode" value="true"/> <hc:chartProperty name="plotOptions.bar.pointWidth"> <hc:propertyExpression><![CDATA[30]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="com.jaspersoft.studio.highcharts.dataconfiguration.simple" value="true"/> <hc:chartProperty name="plotOptions.series.dataLabels.formatter"> <hc:propertyExpression><![CDATA["function(){ var val = this.y; if(val == 0){return '';} else return val+'%';}"]]></hc:propertyExpression> </hc:chartProperty> </hc:chartSetting> <multiAxisData> <multiAxisDataset> <dataset resetType="Report"/> </multiAxisDataset> <dataAxis axis="Rows"> <axisLevel name="Level1"> <labelExpression><![CDATA["Level Label expression"]]></labelExpression> <axisLevelBucket order="None" class="java.lang.Comparable"> <bucketExpression><![CDATA[$F{category}]]></bucketExpression> </axisLevelBucket> </axisLevel> </dataAxis> <dataAxis axis="Columns"> <axisLevel name="Status"> <labelExpression><![CDATA[]]></labelExpression> <axisLevelBucket order="None" class="java.lang.Comparable"> <bucketExpression><![CDATA[$F{series}]]></bucketExpression> </axisLevelBucket> </axisLevel> </dataAxis> <multiAxisMeasure name="Measure1" class="java.lang.Number" calculation="Nothing"> <labelExpression><![CDATA[""]]></labelExpression> <valueExpression><![CDATA[$F{seriesvalue}]]></valueExpression> </multiAxisMeasure> </multiAxisData> <hc:series name="Measure1"/> </hc:chart> </componentElement> <componentElement> <reportElement x="20" y="0" width="480" height="460" uuid="38ecda02-7426-46af-96f2-e50ed771ee53"> <property name="com.jaspersoft.studio.unit.width" value="px"/> <property name="com.jaspersoft.studio.unit.height" value="px"/> </reportElement> <hc:chart xmlns:hc="http://jaspersoft.com/highcharts" xsi:schemaLocation="http://jaspersoft.com/highcharts http://jaspersoft.com/schema/highcharts.xsd" type="StackedPercentBar"> <hc:chartSetting name="default"> <hc:chartProperty name="title.text" value=""/> <hc:chartProperty name="credits.enabled" value="false"/> <hc:chartProperty name="credits.href" value=""/> <hc:chartProperty name="credits.text" value=""/> <hc:chartProperty name="yAxis.title.text" value=""/> <hc:chartProperty name="chart.zoomType" value="xy"/> </hc:chartSetting> <multiAxisData> <multiAxisDataset> <dataset resetType="Report"/> </multiAxisDataset> <dataAxis axis="Rows"> <axisLevel name="Level1"> <labelExpression><![CDATA["Level Label expression"]]></labelExpression> <axisLevelBucket order="None" class="java.lang.Comparable"> <bucketExpression><![CDATA[$F{category}]]></bucketExpression> </axisLevelBucket> </axisLevel> </dataAxis> <dataAxis axis="Columns"> <axisLevel name="series"> <labelExpression><![CDATA[]]></labelExpression> <axisLevelBucket order="None" class="java.lang.Comparable"> <bucketExpression><![CDATA[$F{series}]]></bucketExpression> </axisLevelBucket> </axisLevel> </dataAxis> <multiAxisMeasure name="Measure1" class="java.lang.Number" calculation="Nothing"> <labelExpression><![CDATA[""]]></labelExpression> <valueExpression><![CDATA[$F{seriesvalue}]]></valueExpression> </multiAxisMeasure> </multiAxisData> <hc:series name="Measure1"/> </hc:chart> </componentElement> </band> </summary></jasperReport> gg
  8. To display data labels above the HTML5 column/bar vizz in jasper design studio add the following advanced properties PlotOptions > column > dataLabels crop = false enabled=true overflow=justify To have fixed intervals for y-axis add the below advanced property yAxis > tickInterval=10 Sample output of column chart JRXML ( Works in >= 7.9.0 pro only) <?xml version="1.0" encoding="UTF-8"?><!-- Created with Jaspersoft Studio version 7.9.0.final using JasperReports Library version 6.16.0-48579d909b7943b64690c65c71e07e0b80981928 --><jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="HTML5ColumnGraphAdvancedProperties" pageWidth="800" pageHeight="842" columnWidth="760" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="89be97f5-686b-44fb-94cc-064df05eb383"> <property name="com.jaspersoft.studio.data.sql.tables" value=""/> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="foodmartVeeraTraining"/> <property name="ireport.jasperserver.url" value="http://localhost:8080/jasperserver-pro/"/> <property name="ireport.jasperserver.user" value="superuser"/> <property name="ireport.jasperserver.reportUnit" value="/JasperReports2021/Reports/HTML5ColumnGraphAdvancedProperties"/> <property name="com.jaspersoft.studio.unit." value="pixel"/> <property name="com.jaspersoft.studio.unit.pageHeight" value="pixel"/> <property name="com.jaspersoft.studio.unit.pageWidth" value="pixel"/> <property name="com.jaspersoft.studio.unit.topMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.bottomMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.leftMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.rightMargin" value="pixel"/> <property name="com.jaspersoft.studio.unit.columnWidth" value="pixel"/> <property name="com.jaspersoft.studio.unit.columnSpacing" value="pixel"/> <property name="ireport.jasperserver.report.resource" value="/JasperReports2021/Reports/HTML5ColumnGraphAdvancedProperties_files/main_jrxml"/> <queryString language="SQL"> <![CDATA[select 'Category1' category, 22 barvaluesunionselect 'Category2' , 72unionselect 'Category3' , 22unionselect 'Category4' , 38unionselect 'Category5' , 61unionselect 'Category6' , 81unionselect 'Category7' , 78unionselect 'Category8' , 50]]> </queryString> <field name="category" class="java.lang.String"> <property name="com.jaspersoft.studio.field.name" value="category"/> <property name="com.jaspersoft.studio.field.label" value="category"/> </field> <field name="barvalues" class="java.lang.Integer"> <property name="com.jaspersoft.studio.field.name" value="barvalues"/> <property name="com.jaspersoft.studio.field.label" value="barvalues"/> </field> <sortField name="category"/> <background> <band splitType="Stretch"/> </background> <summary> <band height="425" splitType="Stretch"> <componentElement> <reportElement x="0" y="78" width="760" height="347" uuid="b68859b7-bfb6-44bd-b385-e4770743827a"/> <hc:chart xmlns:hc="http://jaspersoft.com/highcharts" xsi:schemaLocation="http://jaspersoft.com/highcharts http://jaspersoft.com/schema/highcharts.xsd" type="Column"> <hc:chartSetting name="default"> <hc:chartProperty name="title.text" value=""/> <hc:chartProperty name="credits.enabled" value="false"/> <hc:chartProperty name="credits.href" value=""/> <hc:chartProperty name="credits.text" value=""/> <hc:chartProperty name="yAxis.title.text" value=""/> <hc:chartProperty name="chart.zoomType" value="xy"/> <hc:chartProperty name="colors_customSimpleMode" value="true"/> <hc:chartProperty name="colors"> <hc:propertyExpression><![CDATA[Arrays.asList("#019CDE","#434348","#90ed7d","#f7a35c","#8085e9","#f15c80","#e4d354","#2b908f","#f45b5b","#91e8e1")]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="plotOptions.column.dataLabels.enabled_customSimpleMode" value="true"/> <hc:chartProperty name="plotOptions.column.dataLabels.enabled"> <hc:propertyExpression><![CDATA[true]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="yAxis.tickInterval_customSimpleMode" value="true"/> <hc:chartProperty name="yAxis.tickInterval"> <hc:propertyExpression><![CDATA[10]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="plotOptions.column.dataLabels.crop_customSimpleMode" value="true"/> <hc:chartProperty name="plotOptions.column.dataLabels.crop"> <hc:propertyExpression><![CDATA[false]]></hc:propertyExpression> </hc:chartProperty> <hc:chartProperty name="plotOptions.column.dataLabels.overflow" value="none"/> <hc:chartProperty name="legend.enabled_customSimpleMode" value="true"/> <hc:chartProperty name="legend.enabled"> <hc:propertyExpression><![CDATA[false]]></hc:propertyExpression> </hc:chartProperty> </hc:chartSetting> <multiAxisData> <multiAxisDataset> <dataset resetType="Report"/> </multiAxisDataset> <dataAxis axis="Rows"> <axisLevel name="Level1"> <labelExpression><![CDATA["Level Label expression"]]></labelExpression> <axisLevelBucket order="None" class="java.lang.Comparable"> <bucketExpression><![CDATA[$F{category}]]></bucketExpression> </axisLevelBucket> </axisLevel> </dataAxis> <dataAxis axis="Columns"/> <multiAxisMeasure name="Measure1" class="java.lang.Number" calculation="Nothing"> <labelExpression><![CDATA["Percentage"]]></labelExpression> <valueExpression><![CDATA[$F{barvalues}]]></valueExpression> </multiAxisMeasure> </multiAxisData> <hc:series name="Measure1"/> </hc:chart> </componentElement> <textField> <reportElement mode="Opaque" x="0" y="0" width="760" height="70" forecolor="#FFFFFF" backcolor="#0071C0" uuid="57041ecf-98e9-44f9-a817-17eba3daf5cc"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="16" isBold="true"/> </textElement> <textFieldExpression><![CDATA["HTML5 Column Graph Advanced Properties in Jaspersoft Design Studio"]]></textFieldExpression> </textField> </band> </summary></jasperReport> I hope you found this helpful. For Jaspersoft or QA Automation video tutorials refer this page.
  9. Would this be of any help ? an older post, but details the same concept that you are looking for. https://jasper-bi-suite.blogspot.com/2014/04/drill-down-functionality-example-on.html
  10. This post outlines about - how to integrate Extent Report for cucumber 7 that is integrated with TestNG, Selenium Java and Maven. You can clone the complete example from this GitHub repo or down load the zip archive file here. This code has two cucumber scenarios independent of each other but uses the same Background in the feature files. And, I've deliberately failing these scenarios to view the screen shot attachments in Extent Report(Spark Report). Update this piece of yellow highlighted string from this statement in HRMLoginPage.java so both the scenarios will get succeeded. driver.findElement(By.xpath("BAD//body/div[@id=app]/div[1]/div[1]/div[1]/div[1]/div[2]/div[2]/form[1]/div[1]/div[1]/div[2]/input[1]")).sendKeys(cells.get(0).get(0)); You could also refer this no voice video walkthrough tutorial. NOTE : The best practice is to keep the code under src/test/java or src/test/resources but this makes hard to have the executable jar crated, so code should reside under src/main/java or src/main/resources. Project outline: Step 1: Add the following dependency to the pom.xml file<dependency> <groupId>tech.grasshopper</groupId> <artifactId>extentreports-cucumber7-adapter</artifactId> <version>1.7.0</version></dependency>Step 2 : Add the extent cucumber adapter as plugin in the @CucumberOptions Cucumber options are normally given in the Cucumber Test Runner class, for instance in RunCucumberTest. java plugin = { "pretty", "json:target/cucumber-reports/cucumber.json","html:target/cucumber-reports/cucumberreport.html","com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"}, Step 3 : Create extent.properties file in src/main/resources and add below properties extent.reporter.spark.start=true extent.reporter.spark.out=target/SparkReport/Spark.html screenshot.dir=target/screenshots/ screenshot.rel.path=../screenshots/ If we want to generate the extent report(say Spark report) in an executable jar file, add the plugin in main method as shown in below BasePage.java. When run the cucumber scenarios from jar file , the jar generates "target" folder and inside it we can find the Extent Report that is Spark.html BasePage.java package com.sadakar.common;import org.openqa.selenium.WebDriver;import io.cucumber.core.cli.Main;public class BasePage { public static WebDriver driver; public static void main(String args[]) throws Throwable { try { Main.main(new String[] { "-g","com.sadakar.common", "-g","com.sadakar.stepdefinitions", "-g","com.sadakar.testng.runner", "classpath:features", "-t","@SmokeTest", "-p", "pretty", "-p", "json:target/cucumber-reports/cucumber.json", "-p", "html:target/cucumber-reports/cucumberreport.html", "-p","com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", "-m" } ); } catch (Exception e) { e.printStackTrace(); System.out.println("Main method exception : " + e); } }} Save the project and run it as TestNG from eclipse or you could run the scenarios from the executable jar file and analyze the reports generated in "target" folder. The Extent Report(Spark.html) with successful execution should look as shown in below image. Now, what if you want to attach screen shots for the failed scenarios ? The location is given the extent.properties file screenshot.dir=target/screenshots/ screenshot.rel.path=../screenshots/ In order to get the screen shots , add below piece of code in Cucumber @After hook with order=2 since the order=1 is used to quit the driver after each scenario. This order plays a vital role in terms of attaching screen short after a failed scenario. if ((scenario.isFailed())) { final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); scenario.attach(screenshot, "image/png", scenario.getName());} package com.sadakar.common;import java.time.Duration;import org.openqa.selenium.OutputType;import org.openqa.selenium.TakesScreenshot;import org.openqa.selenium.chrome.ChromeDriver;import io.cucumber.java.After;import io.cucumber.java.Before;import io.cucumber.java.Scenario;public class Hooks extends BasePage { @Before //Cucumber hook - runs for each scenario public static void setupDriver() throws InterruptedException { System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30)); } @After(order=1) //Cucumber hook - runs for each scenario public static void quitDriver() throws Exception { driver.quit(); } @After(order = 2) // Cucumber After Hook with order 1 public void takeScreenShotOnFailedScenario(Scenario scenario) { System.out.println("Taking screenshot from Cucumber After hook with order=2 if the scenario fails"); if ((scenario.isFailed())) { final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); scenario.attach(screenshot, "image/png", scenario.getName()); } }} The same code base above is given to have bad login so it will fail both the scenarios and so the Sprak.html look like below with the screen shot attached. References: https://github.com/grasshopper7/extentreports-cucumber7-adapter That's all we have to do to integrate Extent Report with cucumber 7. I hope you found this demo is useful! Keep an eye on this space for interesting automation updates and do subscribe the YouTube channel.
  11. In this blog post , we will learn majorly the following topics. 1. How to create an executable jar for cucumber+selenium+testng+maven project ? 2. How to run scenarios from generated jar ? To create an executable jar for maven project there are many jar plug-in's available in the maven space. In this example, I'd like to demonstrate it using maven-assembly-plugin. The demo project for HRM application can be found at GitHub or download this maven zip file You could also watch this no voice video tutorial for quick references (Pls do subscribe for more automation updates) Now, let's see the core part that we start with pom.xml We need to have the maven-assembly-plugin is given the pom file, i.e., add below piece of code in the pom.xml file. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>com.sadakar.common.BasePage</mainClass> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions></plugin> In a java class, using "main" method, we need to pass the glue code, tags, plug-ins and etc that are related to cucumber as arguments. For example, I've used, BasePage.java class that should contain normal "main" method and inside it use Main.main(....) to pass cucumber arguments so the scenarios based on tags would be runnable from command line. import package : import io.cucumber.core.cli.Main; in the BasePage.java class and the passing of arguments are shown in below class. BasePage.javapackage com.sadakar.common;import org.openqa.selenium.WebDriver;import io.cucumber.core.cli.Main;public class BasePage { public static WebDriver driver; public static void main(String args[]) throws Throwable { try { Main.main(new String[] { "-g","com.sadakar.common", "-g","com.sadakar.stepdefinitions", "-g","com.sadakar.testng.runner", "classpath:features", "-t","@HRMLogin", "-p", "pretty", "-p", "json:target/cucumber-reports/cucumber.json", "-p", "html:target/cucumber-reports/cucumberreport.html", "-m" } ); } catch (Exception e) { e.printStackTrace(); System.out.println("Main method exception : " + e); } }} In eclipse, build the project using below command: Ensure that any open folders, command prompts, chrome drivers in task manager are all closed. Clean the project and then build it. clean package assembly:single -Dmaven.test.skip=true Using -Dmaven.test.skip=true option we can skip the tests while the project builds! Click on the images to view them in gallery mode so the content provided is clear! This is how the log looks like when the build is in progress and is completed. SLF4J: Class path contains multiple SLF4J bindings.SLF4J: Found binding in [jar:file:/D:/softwares/Eclipse/eclipse-java-2021-09-R-win32-x86_64/eclipse/plugins/org.eclipse.m2e.maven.runtime.slf4j.simple_1.18.0.20210618-2246/jars/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: Found binding in [file:/D:/softwares/Eclipse/eclipse-java-2021-09-R-win32-x86_64/eclipse/configuration/org.eclipse.osgi/5/0/.cp/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]SLF4J: Class path contains multiple SLF4J bindings.SLF4J: Found binding in [jar:file:/D:/softwares/Eclipse/eclipse-java-2021-09-R-win32-x86_64/eclipse/plugins/org.eclipse.m2e.maven.runtime.slf4j.simple_1.18.0.20210618-2246/jars/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: Found binding in [file:/D:/softwares/Eclipse/eclipse-java-2021-09-R-win32-x86_64/eclipse/configuration/org.eclipse.osgi/5/0/.cp/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory][INFO] Scanning for projects...[INFO] [INFO] --< CucumberTestNGSeleniumExecutableJar:CucumberTestNGSeleniumExecutableJar >--[INFO] Building CucumberTestNGSeleniumExecutableJar 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Deleting C:\Users\sadakarp\eclipse-workspace\CucumberTestNGSeleniumExecutableJar\target[INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] Copying 3 resources[INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Changes detected - recompiling the module![INFO] Compiling 5 source files to C:\Users\sadakarp\eclipse-workspace\CucumberTestNGSeleniumExecutableJar\target\classes[INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Not copying test resources[INFO] [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Not compiling test sources[INFO] [INFO] --- maven-surefire-plugin:3.0.0-M7:test (default-test) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Tests are skipped.[INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Building jar: C:\Users\sadakarp\eclipse-workspace\CucumberTestNGSeleniumExecutableJar\target\CucumberTestNGSeleniumExecutableJar-0.0.1-SNAPSHOT.jar[INFO] [INFO] --- maven-assembly-plugin:3.1.1:single (default-cli) @ CucumberTestNGSeleniumExecutableJar ---[INFO] Building jar: C:\Users\sadakarp\eclipse-workspace\CucumberTestNGSeleniumExecutableJar\target\CucumberTestNGSeleniumExecutableJar-0.0.1-SNAPSHOT-jar-with-dependencies.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 26.979 s[INFO] Finished at: 2022-09-10T20:21:45+05:30[INFO] ------------------------------------------------------------------------ maven-assembly-plugin generates two jar files, they are 1. CucumberTestNGSeleniumExecutableJar-0.0.1-SNAPSHOT.jar2. CucumberTestNGSeleniumExecutableJar-0.0.1-SNAPSHOT-jar-with-dependencies.jar The jar with the dependencies is called fat jar file and this is the one we call as "executable" or "runnable" jar. Make sure that this jar contains the MANIFEST.MF file containing the class that has the main method. Use jar extract tools to view the content inside the jar, I've used "Java Decompiler". The MANIFEST.MF file should contain all the dependencies with Main-Class:com.sadakar.common.BasePage as shown in below. MANIFEST.MFManifest-Version: 1.0Created-By: Apache Maven 3.8.1Built-By: sadakarpBuild-Jdk: 16.0.2Class-Path: cucumber-java-7.1.0.jar cucumber-core-7.1.0.jar cucumber-ghe rkin-7.1.0.jar cucumber-gherkin-messages-7.1.0.jar messages-17.1.1.jar tag-expressions-4.1.0.jar cucumber-expressions-13.0.1.jar datatable-7.1 .0.jar cucumber-plugin-7.1.0.jar docstring-7.1.0.jar html-formatter-17. 0.0.jar create-meta-6.0.4.jar apiguardian-api-1.1.2.jar cucumber-testng -7.1.0.jar selenium-java-4.3.0.jar selenium-api-4.3.0.jar selenium-chro me-driver-4.3.0.jar auto-service-annotations-1.0.1.jar auto-service-1.0 .1.jar auto-common-1.2.jar guava-31.1-jre.jar failureaccess-1.0.1.jar l istenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar jsr305-3. 0.2.jar checker-qual-3.12.0.jar error_prone_annotations-2.11.0.jar j2ob jc-annotations-1.3.jar selenium-chromium-driver-4.3.0.jar selenium-json -4.3.0.jar selenium-devtools-v101-4.3.0.jar selenium-devtools-v102-4.3. 0.jar selenium-devtools-v103-4.3.0.jar selenium-devtools-v85-4.3.0.jar selenium-edge-driver-4.3.0.jar selenium-firefox-driver-4.3.0.jar seleni um-ie-driver-4.3.0.jar selenium-opera-driver-4.3.0.jar selenium-remote- driver-4.3.0.jar netty-buffer-4.1.78.Final.jar netty-codec-http-4.1.78. Final.jar netty-codec-4.1.78.Final.jar netty-handler-4.1.78.Final.jar n etty-common-4.1.78.Final.jar netty-transport-classes-epoll-4.1.78.Final .jar netty-transport-classes-kqueue-4.1.78.Final.jar netty-transport-na tive-epoll-4.1.78.Final.jar netty-transport-native-kqueue-4.1.78.Final. jar netty-transport-native-unix-common-4.1.78.Final.jar netty-transport -4.1.78.Final.jar netty-resolver-4.1.78.Final.jar opentelemetry-api-1.1 5.0.jar opentelemetry-context-1.15.0.jar opentelemetry-exporter-logging -1.15.0.jar opentelemetry-sdk-metrics-1.15.0.jar opentelemetry-sdk-logs -1.15.0-alpha.jar opentelemetry-sdk-common-1.15.0.jar opentelemetry-sdk -extension-autoconfigure-spi-1.15.0.jar opentelemetry-sdk-extension-aut oconfigure-1.15.0-alpha.jar opentelemetry-sdk-trace-1.15.0.jar opentele metry-sdk-1.15.0.jar opentelemetry-semconv-1.15.0-alpha.jar jtoml-2.0.0 .jar byte-buddy-1.12.10.jar commons-exec-1.3.jar async-http-client-2.12 .3.jar async-http-client-netty-utils-2.12.3.jar netty-codec-socks-4.1.6 0.Final.jar netty-handler-proxy-4.1.60.Final.jar netty-transport-native -epoll-4.1.60.Final-linux-x86_64.jar netty-transport-native-kqueue-4.1. 60.Final-osx-x86_64.jar reactive-streams-1.0.3.jar netty-reactive-strea ms-2.0.4.jar slf4j-api-1.7.30.jar jakarta.activation-1.2.2.jar selenium -http-4.3.0.jar failsafe-3.2.4.jar selenium-safari-driver-4.3.0.jar sel enium-support-4.3.0.jar testng-7.1.0.jar jcommander-1.72.jar guice-4.1. 0-no_aop.jar javax.inject-1.jar aopalliance-1.0.jar snakeyaml-1.21.jar .Main-Class: com.sadakar.common.BasePage Now, let's run the jar file: Double click on the executable jar, it will start executing the scenarios! Or use below command to run the cucumber scenarios Command is updated on 18 June 2023 java -jar -Dcucumber.filter.tags="@HRMLogin" CucumberTestNGSeleniumExecutableJar-0.0.1-SNAPSHOT-jar-with-dependencies.jar This execution, will generate, cucumber reports in "target" folder where the jar is located. The report is based on the plug-in(s) that we provide in BasePage.java file. For example, we gave it as "-p", "json:target/cucumber-reports/cucumber.json", "-p", "html:target/cucumber-reports/cucumberreport.html", click on the "cucumberreport.html" file to analyze the report generated. That's all we have to do to create an executable cucumber, testng jar file using maven and to run the scenarios from it. I hope you found this write-up useful, keep watch this blog site for more automation!
  12. What are Waits in selenium ? 1) Implicit wait 2) Explicit wait 1) Implicit wait a) implicitlyWait() b) pageLoadTimeout() c) setScriptTimeout() 2) Explicit wait a) WebDriverWait b) Fluent Implicit wait | implicitlyWait()implicitlyWait is applied to all the web elements on the web page.It will throw "No Such Element Exception" after reaching the time. Implicit wait stays in place for the entire duration for which the browser is open.The default value of implicit wait is 0.Implicit wait is applied for the lifetime of the Webdriver, it can extend the test execution times to a large value depending on the number of elements on which it is being called. When to use implicitlyWait? It is recommended to use implicit wait only when you are in complete control of the script.Example: import this package : import java.time.Duration; driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(60)) Implicit wait | pageLoadTimeout()It waits for the page to load completely for the specified number of seconds. Default value is : 0 Example: WebDriver driver = new ChromeDriver();driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);driver.get("https://demoqa.com/login");WebDriver will wait for a maximum of 30 seconds before moving ahead with the interaction with the element. Implicit wait | setScriptTimeout()The setScriptTimeout command waits for the asynchronous parts of the web page to finish loading for a specified number of seconds.Example: driver.manage().timeouts().setScriptTimeout(15, TimeUnit.SECONDS);((JavascriptExecutor) driver).executeScript("alert('hello world');");((JavascriptExecutor) driver).executeAsyncScript("window.setTimeout(arguments[arguments.length - 1], 500);");WebDriver will wait for a maximum of 15 seconds before moving ahead with the interaction with the element. Explicit wait | WebDriverWaitIt is a conditional wait strategy Wait until the the condition specified becomes true or the time duration is elapsed. Explicit wait is only applied on the specified element. Commonly used conditions are : presenceOfElementLocated() elementToBeClickable() visibilityOfElementLocated()WebDriverWait class and ExpectedConditions specifies the time and condition for which the WebDriver needs to wait. Example-1 : WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(30)); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id=searchBox]")));Example-2: WebElement searchBox = new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@id=searchBox]")));Example-3: WebElement searchBox = new WebDriverWait(driver, Duration.ofSeconds(30)).until(driver -> driver.findElement(By.name("//input[@id=searchBox]"))); Explicit wait| Fluent waitFluent wait is similar to Explicity wait It takes an additional argument frequency i.e., polling time. frequency number tells the WebDriver to keep on checking for the element at regular time intervals wait till the maximum of "Duration.ofSeconds"If the element becomes avaialble earlier, we proceed with the test execution and finish quickly. Example: Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(NoSuchElementException.class);Maximum waiting time is 30 seconds polling time is 5 seconds WebDriver keeps on checking for the element for every 5 seconds to a maximum of 30 seconds ignoring will ignore the exception NoSuchElementException while the driver finds the element in the maximum time. When to use ? When dealing with AJAX elements Which is best wait ? When to use which wait ? Explicit wait : Saves the time and is not applicable for all elements.Wait only based on condition and time for a specified element. Implicit wait : It is applied once for all the elements and the next wait cycle starts once the previous one completes. Implicitly waits needs a better understanding of scripts.There is no best type of wait, based on the demand of the element find strategy we use any of the waits above. NOTE: Do not mix implicit and explicit waits! Doing so can cause unpredictable wait times. For example, setting an implicit wait of 20 seconds and an explicit wait of 35 seconds could cause a timeout to occur after 25 seconds. What is polling time ? The polling time (or polling interval) is the time interval in which Selenium starts searching again after the last failed try. It depends on the type of browser driver you are working on. Some may have 500 milliseconds while some may have 1 second as polling time. The polling time is inbuild in implicitlyWait and there is no way to modify the time interval. The default pooling period for implicit and explicit wait is 250 ms. During implicitlyWait, the WebDriver will poll the DOM for certain specified time units while trying to find any element. If the element is found earlier, the test executes at that point otherwise the WebDriver waits for the specified duration. Thread.sleep()Thread.sleep() pauses the executionSleep is a static method that belongs to the ‘Thread’ class of Java.Thread.sleep() sets the condition to an exact time period to wait.What is the difference between sleep and selenium waits ? Thread.sleep() will stop the execution of the script for the time specified in the script, irrespective of the fact that the element on the web page has been found.Selenium waits do not wait for the complete duration of time. If the WebDriver is able to find the element before the specified time duration, it moves on to the next line of code. This helps in reducing the overall time of script execution by a considerable margin.Selenium setSpeed()setSpeed() sets the desired speed of execution or delays execution by a specified amount of time before each operation.
  13. How to configure postman/newman API tests in Azure DevOps Export the postman collection and environment Push the collection/environment to "Azure Repos Git" repositoryNavigate to Pipeline page in Azure DevOps and click on "New pipeline" button on the top right corner. Click on "Use the classic editor" link in the bottom to create a pipeline without YAML.Select the source for the postman testsSelect a template > Click on "Empty job"A new pipe line is created with default name Add the tasksInstall newman Newman command to run the testsPublish Test results Save the pipe line and Queue(run the pipeline) Analysis of Junit ReportAnalysis of published report Let's look into each of the steps above in detail. Export the postman collection and environment as .json files Create a Collection, create a GET request, write tests for the requestHere is a sample request created : https://learning.postman.com/docs/getting-started/sending-the-first-request/Tests written for the above GET request are as followsNOTE: For the demonstration purposes, I've not taken environment for this example. pm.test("Status code is 200 OK", function () { pm.response.to.have.status(200);});pm.test("Response time is less than 10s", function () { pm.expect(pm.response.responseTime).to.be.below(10000);});pm.test("Body contains url",() => { pm.expect(pm.response.text()).to.include("http://postman-echo.com/get");});Collection Name : 00Test.postman_collection.jsonPush the collection/environment to "Azure Repos Git" repository Use git commit and push the code to Azure Git repositoryClick on the image below to get the best view. Navigate to Pipeline page in Azure DevOps and click on "New pipeline" button on the top right corner. Click on "Use the classic editor" link in the bottom to create a pipeline without YAML.Select the source for postman testsSelect the "Team Project", "Repository", "Branch" and click on Continue button Select a template > Click on "Empty job" A new pipe line is created with default name Set the below basic properties and the remaining are optional and can be configured on demand basis. Display name : Agent job1 Agent pool : <inherit from pipeline> Add the tasks To add the tasks click on + button on the Agent job. I am taking 3 tasks for the tests to run, they are as follows. Install newman Newman command to run the tests Publish Test resultsInstall newman Search for the command line plugin at the top right corner and then Add the command line task. Fill the required properties for the task added, for instance, we install postman command line tool that is newman using npm package. Display name : Install newman Script : npm install -g newman The corresponding YAML script to install the newman is steps:- script: | npm install -g newman displayName: 'Install newman' Newman command to run the testsAdd one more command line plug-in to run the postman API tests (This we can do in the previous step itself, I wanted to separate out the installation task to the test execution task so the second command line plugin). Use below script command to run the collection Display name : Newman command to run testsScript: newman run 00Test.postman_collection.json --reporters cli,junit --reporter-junit-export Results\junitReport.xml Format/Syntax: Postman collection with environment newman run <PostmanCollection.json> -e <Environment.json> --reporters cli,junit --reporter-junit-export Results\junitReport.xml Ensure that the working directory has the code path populated. Default Working Directory format is : $(System.DefaultWorkingDirectory) Corresponding YAML scriptsteps:- script: 'newman run 00Test.postman_collection.json --reporters cli,junit --reporter-junit-export Results\junitReport.xml' displayName: 'Newman command to run tests' Publish test results: Search for Publish Test Results plugin and add it as next task for the job. Configure the below basic properties Display Name : Publish Test Results **/TEST-*.xml ( It could be any name, I used the generated name)Test result format : JunitTest results files: $(System.DefaultWorkingDirectory)\Results\*.xml Search folder : $(System.DefaultWorkingDirectory) Save the pipe line and Queue(run the pipeline) Save the pipe line Queue and run the pipe line As the pipe line queued we navigate to the run console of the pipe line, from this console click on "Agent job1" in the bottom which is in process. Agent job1 displays the tasks to perform by the pipeline as shown in below image. This includes the default tasks along with the tasks configured by us. All the tasks in the job has successfully ran so the next thing is to analyze the junit report. Analysis of Junit ReportBe on the pipe line run console to view the report. If there are any unexpected blockers while executing the tasks, the junit report will not be generated. If there are any failures in the asserstions/tests for the postman junit report will be generated. The report can be analyzed in the Tests tab as shown in below image. Analysis of Published Report Click on Publish Test Results task from the pipe line execution and the console make note of the URL where the results are published. Open the URL in a new tab and start analyzing the results. Go to the Runs section from Azure DevOps wizard as shown in below and start analyzing the published report. In case of any test failures, Create bug or update the result to to the test case! This is how we integrate postman/newman API tests in Azure DevOps pipe line for the continuous integration (CI) . I hope this helped a bit, keep an eye on this portal for more automation updates.
  14. Xpath's text() returns the text of selected element and it doesn't fit into the WebElement's findElement method. So remove the text() from the xpath and then apply the getText() method on WebElement. For example: //*[@id=formsearch]/fieldset/legend/text() will identify the text of the WebElement and we can't use it for findElement instead //*[@id=formsearch]/fieldset/legend will identify the WebElement and then on this we can use getText() method of the element. org.openqa.selenium.InvalidSelectorException: invalid selector: The result of the xpath expression "//*[@id=formsearch]/fieldset/legend/text()" is: [object Text]. It should be an element. (Session info: chrome=104.0.5112.81)For documentation on this error, please visit: https://selenium.dev/exceptions/#invalid_selector_exceptionBuild info: version: '4.3.0', revision: 'a4995e2c09*'System info: host: 'SADAKARP', ip: '200.123.4.3', os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.3'Driver info: org.openqa.selenium.chrome.ChromeDriverCommand: [f12f1c7e2c818403564e8712964c6af2, findElement {using=xpath, value=//*[@id=formsearch]/fieldset/legend/text()}]Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 104.0.5112.81, chrome: {chromedriverVersion: 104.0.5112.79 (3cf3e8c8a07d..., userDataDir: C:\Users\sadakarp\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:65004}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: WINDOWS, proxy: Proxy(), se:cdp: ws://localhost:65004/devtoo..., se:cdpVersion: 104.0.5112.81, 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: f12f1c7e2c818403564e8712964c6af2 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:200) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:133) at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184) at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:167) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:142) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:569) at org.openqa.selenium.remote.ElementLocation$ElementFinder$2.findElement(ElementLocation.java:162) at org.openqa.selenium.remote.ElementLocation.findElement(ElementLocation.java:60) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:387) at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:379) at com.sadakar.cucumber.stepdef.payers.Products.routeToolPageNavigationValidation(Products.java:45) at ✽.Search for Medicaid Florida (FL) payer and navigate to RouteTool page(classpath:features/Products.feature:12)
×
×
  • Create New...