How to launch browser using selenium with cucumber - cucumber

I am newbie for cucumber framework, I have worked on selenium webdriver using testNG framework. I have to start cucumber framework, I have installed cucumber plugin to eclipse but dont know how to start writting code.
And what is the difference between cucumber and cucumber-jvm, and which is the best?
Could anyone pls help me out?
Thanks in advance.

You can find lots of info on what dependecies you should use for your project on the Cucumber main site Cucumber Documentation
Cucumber base is Ruby
Cucumber-JVM is Java
start with creating a src/test/resources
create a file named anything you want (keep it to the thing you want to test) and end it with .feature
Feature: Calculator should work accourding to standard calculator devices
Scenario: addition
Given a calculator I just turned on
When I add 4 and 5
Then the result is 9
put this in as a guide line and try to run it. it should give you a call missing steps.
create a new java file in src/test/java and call it RunCukesTest this wil later be the starter of all your features.
the output you just got from the feature in the console can be put in a .java call it something to do with the feature like CalculatorSteps.java put this in the same folder as your RunCukesTest.java
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = false,
plugin = {"pretty","json:target/cucumber.json"} ,
features = "src/test/resources/cucumber",
tags = "~#ignore"
)
public class RunCukesTest {
}
this is the basic you need to start using Cucumber (there is a start example on github)
Now the Selenium question
you will have to initiate a WebDriver _driver;
with driver you create a new ChromeDriver or FireFoxDriver etc
some browsers need a installation ChromeDriver firefox is built in (to my best knowledge)
see the code below
ask if there is anything you don't get
import java.util.concurrent.TimeUnit;
import cucumber.api.java.en.*;
import org.eclipse.jetty.util.thread.Timeout;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class NavigationSteps {
WebDriver _driver;
#Given("^i am at \"([^\"]*)\"$")
public void i_am_at_home(String arg1) throws Throwable {
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
_driver = new ChromeDriver();
_driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
_driver.get(arg1);
Thread.sleep(500);
}
#When("^i click on \"([^\"]*)\"$")
public void i_click_on(String arg1) throws Throwable {
_driver.findElement(By.linkText(arg1)).click();
Thread.sleep(500);
}
#Then("^i expect the title to be \"(.*?)\"\"(.*?)\"$")
public void i_expect_the_title_to_be(String arg1, String arg2) throws Throwable {
String result = (arg1 + " | " + arg2);
Thread.sleep(200);
assertEquals("Title should be",result,_driver.getTitle());
tearDown();
}
#Then("^Header should contain \"(.*?)\"$")
public void header_should_contain(String arg1) throws Throwable {
Thread.sleep(200);
assertEquals("Title should be", arg1, _driver.findElement(By.xpath(".//*[#id='main']/div[1]/div/h1")).getText());
tearDown();
}
#After
public void tearDown() throws InterruptedException
{
_driver.quit();
}
}
EDIT - answers to the questions in nicer format
feature file calls the java file (Run via RunCukesTest or feature file)
the methods to test go into je java steps file
Feature calculator has a CalculatorSteps.java file the scenario is in the feature file the methods in the steps
No, the console outputs this as a Regex to identify the corresponding step the test u write in the method below it.
Given a calculator I just turned on
results into
#Given ("^a calculator I just turned on$")
public void iCanCallThisAnythingIWant(){
#do something
}
see answer 2
Given When Then are the logical way to read a Scenario to keep things readable it should be used in that way. If you find yourself with a long Given When or Then u can split the sentence with a "and" in between. but it doesn't matter in what way u write them.

Related

groovy is not finding annotated tests

Still new to Groovy and trying to figure out unit testing. I'm trying to use the Junit4 style of testing.
import org.junit.Test
import junit.framework.*
import junit.textui.TestRunner
class DegenerateTestCase {
#Test
void testAlwaysTrue() {
assert true
}
#Test
void someMethodName() {
assert true
}
}
TestRunner.run(DegenerateTestCase)
But when I run the script, I get
There was 1 failure:
warning(junit.framework.TestSuite$1)junit.framework.AssertionFailedError:> No tests found in DegenerateTestCase
This has to be something simple that I'm missing.
I am using Eclipse Java EE IDE for Web Developers, Oxygen.3a Release (4.7.3a). I have the Groovy plugin downloaded from the marketplace (compiler level 2.5).
I tried running it with junit5 which had only one difference which was instead of having import org.junit.Test I had import static org.junit.jupiter.api.Assertions.*. I didnt need import junit.framework.* or import junit.textui.TestRunner I just ran it as is and worked fine.
I then switched to Junit4 and did the same but switched import static org.junit.jupiter.api.Assertions.* to import org.junit.Test and it works.
my code looks like this:
import org.junit.Test
class DegenerateTestCase {
#Test
void testAlwaysTrue() {
assert true
}
#Test
void someMethodName() {
assert true
}
}

Use Gmail API in a keyword in Katalon Studio

I use this tutorial to connect to Gmail API: https://developers.google.com/gmail/api/quickstart/java
I would like to make a keyword in Katalon Studio, which depends on Gmail API.
I modified from sample code that line:
InputStream in = GmailQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
to this:
InputStream ins = new FileInputStream(CREDENTIALS_FILE_PATH);
JAR files are added, project is running and browser window is opened to get token. After successful authorization I got error message:
Caused by: java.lang.NoSuchMethodError:
com.google.api.client.http.HttpRequest.setResponseReturnRawInputStream(Z)Lcom/google/api/client/http/HttpRequest;
UPDATE: List of imported dependencies:
commons-codec-1.15.jar
commons-logging-1.2.jar
google-api-client-1.31.3.jar
google-api-client-extensions-1.6.0-beta.jar
google-api-client-jackson2-1.31.3.jar
google-api-client-java6-1.31.3.jar
google-api-services-gmail-v1-rev110-1.25.0.jar
google-http-client-1.39.1.jar
google-http-client-jackson2-1.39.1.jar
google-oauth-client-java6-1.31.4.jar
google-oauth-client-jetty-1.31.4.jar
guava-30.1.1-jre.jar
httpclient-4.5.13.jar
httpcore-4.4.14.jar
j2objc-annotations-1.3.jar
jackson-core-2.12.2.jar
jsr305-3.0.2.jar
https://docs.katalon.com/katalon-studio/docs/external-libraries.html#exclude-built-in-libraries
With the ability to remove built-in libraries stored in the .classpath file of a project folder, you can replace a built-in library with an external one for flexible libraries usage in a test project.
Requirements
An active Katalon Studio Enterprise license.
Katalon Studio version 7.8.
UPD:
i got katalon 7.9.1 and here how i was able to do it:
add the following class into KS project:
include/scripts/groovy/(default package)/GroovyBox.java
import groovy.lang.*;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.List;
/** run groovy script in isolated classloader*/
public class GroovyBox {
GroovyShell gs;
public GroovyBox(ClassLoader parentCL, Pattern excludeClassPattern ) {
FilteredCL fcl = new FilteredCL(parentCL, excludeClassPattern);
gs = new GroovyShell(fcl);
}
public GroovyBox withClassPath(List<String> classPathList) {
GroovyClassLoader cl = gs.getClassLoader();
for(String cp: classPathList) cl.addClasspath(cp);
return this;
}
public Script parse(String scriptText) {
return gs.parse(scriptText);
}
public static class FilteredCL extends GroovyClassLoader{
Pattern filterOut;
public FilteredCL(ClassLoader parent,Pattern excludeClassPattern){
super(parent);
filterOut = excludeClassPattern;
}
#Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
if(filterOut.matcher(name).matches())throw new ClassNotFoundException("class not found "+ name);
return super.loadClass(name, resolve);
}
}
}
now add a test case - actually you can move code from test case into a class...
import ... /* all katalon imports here*/
assert method1() == 'HELLO WORLD'
def method1() {
def gb = new GroovyBox(this.getClass().getClassLoader().getParent(), ~/^com\.google\..*/)
def script = gb.parse('''
#Grab(group='com.google.api-client', module='google-api-client', version='1.31.3')
import com.google.api.client.http.HttpRequest
def c = HttpRequest.class
println( "methods execute:: "+c.methods.findAll{it.name=='execute'} )
println( "methods setResponseReturnRawInputStream:: "+c.methods.findAll{it.name=='setResponseReturnRawInputStream'} )
println greeting
return greeting.toUpperCase()
''')
script.setBinding([greeting:'hello world'] as Binding)
return script.run()
}
options to define external dependencies:
#Grab(...) as a first line of parsed script - loads all required dependencies from maven central (by default). for example #Grab(group='com.google.api-client', module='google-api-client', version='1.31.3') corresponds to this artifact.
sometimes you need to specify specific maven repository then add #GrabResolver(name='central', root='https://repo1.maven.org/maven2/')
if you want to specify local file dependencies then in the code above:
def gb = new GroovyBox(...).withClassPath([
'/path/to/lib1.jar',
'/path/to/lib2.jar'
])

Cannot get AppInsights working under Spring Boot

I followed the https://learn.microsoft.com/en-us/azure/application-insights/app-insights-java-get-started, but still without success.
I have applicationinsights-web dependency in place via maven
I added ApplicationInsights.xml to main/resources with hardcoded instrumentation key and even with <SDKLogger /> inside
I added the scan path: #ComponentScan({...., "com.microsoft.applicationinsights.web.spring"})
Results:
I see no logs about looking up the configuration file, even if I make the syntax error in in or remove it completely
in debug I see that RequestNameHandlerInterceptorAdapter is instantiated via com.microsoft.applicationinsights.web.spring.internal.InterceptorRegistry, and during calls the preHandle method is called, but calls to ThreadContext.getRequestTelemetryContext() returns always null and nothing more happens
It looks like it is something obvious, but no idea what. What part/classes are responsible for loading the configuration file?
I was a little bit confused with documentation. As mentioned by yonisha, the filter does the whole magic. The following configuration class takes care of creating and adding the filter in Spring Boot application.
import com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
#Configuration
#ComponentScan("com.microsoft.applicationinsights.web.spring")
public class ApplicationInsightsConfiguration {
#Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(appInsightsWebRequestTrackingFilter());
registration.addUrlPatterns("/*");
registration.setName("webRequestTrackingFilter");
registration.setOrder(1);
return registration;
}
#Bean(name = "appInsightsWebRequestTrackingFilter")
public Filter appInsightsWebRequestTrackingFilter() {
return new WebRequestTrackingFilter();
}
Important: It will work nicely if you set the server.context-path property to some value. If not, AI initialization will fail with error
AI: ERROR 03-04-2017 14:11, 20: WebApp name is not found, unable to register WebApp
In order to keep servlet-context empty, I had to implement wrappers for the filter and 2 other classes to override it, but it was a very dirty fix... Would be great, if the name could be passed as a parameter to the filter, but that is not yet possible (https://github.com/Microsoft/ApplicationInsights-Java/issues/359)
In spring boot , We need to configure WebRequestTrackingFilter by extending WebSecurityConfigurerAdapter and overriding configure(HttpSecurity httpSecurity)
#Bean
public WebRequestTrackingFilter applicationInsightsFilterBean() throws Exception {
WebRequestTrackingFilter webRequestTrackingFilter = new WebRequestTrackingFilter();
return webRequestTrackingFilter;
}
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
//other stuff...
httpSecurity.addFilterBefore(applicationInsightsFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
you need to have below configuration also ..
applicationinsights-web dependency in place via maven
added ApplicationInsights.xml to main/resources
Here is newer guide for Spring Boot Application Insights integration that worked well for me just now:
https://github.com/AzureCAT-GSI/DevCamp/tree/master/HOL/java/06-appinsights
The idea is basically what Tomasz has above with some minor differences.
package devCamp.WebApp.configurations;
import javax.servlet.Filter;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.microsoft.applicationinsights.TelemetryConfiguration;
import com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter;
#Configuration
public class AppInsightsConfig {
#Bean
public String telemetryConfig() {
String telemetryKey = System.getenv("APPLICATION_INSIGHTS_IKEY");
if (telemetryKey != null) {
TelemetryConfiguration.getActive().setInstrumentationKey(telemetryKey);
}
return telemetryKey;
}
#Bean
public FilterRegistrationBean aiFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new WebRequestTrackingFilter());
registration.addUrlPatterns("/**");
registration.setOrder(1);
return registration;
}
#Bean(name = "WebRequestTrackingFilter")
public Filter WebRequestTrackingFilter() {
return new WebRequestTrackingFilter();
}
}
The guide at the link above has a full set of instructions and includes client side js and a java log appender example as well. Hope this helps.
The above all method works! However you can try the whole new seamless experience using Application Insights SpringBoot Starter.
https://github.com/Microsoft/ApplicationInsights-Java/blob/master/azure-application-insights-spring-boot-starter/README.md
This is currently in BETA

How to properly quit WebDriver after completing all UI tests with Cucumber

We are using Selenium WebDriver to do UI testing, along with Cucumber. The language is Groovy, and the build tool is Gradle. Because it is expensive to create a WebDriver instance, we want to instantiate only one WebDriver instance and use it through all tests. However, we are having trouble to quit the driver properly after all tests are completed. Namely, the browser process spawned during the tests is still alive after running all the tests.
The code is currently structured like below.
// Test base class
class UITestBase {
WebDriver driver
static {
init()
}
static void init() {
// instantiate a webdriver
}
}
// Entry class of cucumber run
RunWith( Cucumber )
Cucumber.Options(...)
class CukeRunEntry {}
// Cucumber step class
class WhenSteps extends UITestBase {
#When(/^something happens$/)
void something_happens() {
// step implmentation
}
}
So, how can I call driver.quit() after all tests are finished but before gradle finishes the test task (we run the tests with ./gradlew test from command line)? I tried overriding the finalize() method, but that didn't help.
Thank you very much.
If I were you, I would prefer using SharedDriver that you can find here => https://github.com/cucumber/cucumber-jvm/blob/master/examples/java-webbit-websockets-selenium/src/test/java/cucumber/examples/java/websockets/SharedDriver.java
It makes life easier.
Edit
If you don't wish to use SharedDriver, you can add a block like below to the UITestBase class as illustrated in the question:
private static final Thread CLOSE_THREAD = new Thread() {
#Override
public void run() {
try {
driver.quit()
} catch ( Exception e ) {
}
}
}
static {
init()
Runtime.getRuntime().addShutdownHook(CLOSE_THREAD)
}
The above code is essentially what's used in SharedDriver to ensure safe close of the WebDriver instance.

How can I make Selenium tests inside my JSF project?

I have quite big JSF 1.2 project and I want to write some integration tests to it.
The perfect situation will be, when I can run these tests from my project and it opens my browser and makes all the actions (with Selenium), which are written in my test cases. Ofc opening browser is not required when It will run these tests anyway :)
I've tried a few possibilities, anyway I still can't attach any selenium library to my project and I realized that I just dont know where to start - can you give me some direction?
might help you ,
you can write you test logic inside test method
package com.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.fail;
public class test1 {
private WebDriver driver;
private String baseUrl;
private StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new InternetExplorerDriver();
driver = new ChromeDriver();
baseUrl = "http://www.google.com";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Ignore
#Test
public void test1() throws Exception {
// your test code
}
#After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
you just need call test1 class which you want to test it .
it will be automatically working on it .

Resources