Not able to implement DataTable cucumber feature in QAF - selenium

I am trying to get the vales as DataTable in cucumber. How can this be done in QAF ?
#test
Scenario: DataTable Examples
Given I am on github login page
And I enter usernames and passwords "${args[0]}"
| testuser_1 | Test#153 |
StepDefinition
#And("^I enter usernames and passwords \"([^\"]*)\"$")
public void iEnterUsernamesAndPasswords(Map<Object, Object> data) {
System.out.println("------------->" +data.get(0));
}
Error Msg:
[WINDOWS 91.0.4472.77]: ▀ ▀ ▀ END STEP: Given I am on github login page ▀ ▀ ▀
17:28:22.608 [[WINDOWS 91.0.4472.77]] ERROR com.qmetry.qaf.automation.step.StepNotFoundException -
/**
* Auto-generated code snippet by QMetry Automation Framework.
*/
#QAFTestStep(description="I enter usernames and passwords {0}{1}")
public void iEnterUsernamesAndPasswords(String str0,Object[] objArray1){
//TODO: remove NotYetImplementedException and call test steps
throw new NotYetImplementedException();
}
/**
* Auto-generated code snippet by QMetry Automation Framework.
*/
#QAFTestStep(description="I enter usernames and passwords {0}{1}")
public void iEnterUsernamesAndPasswords(String str0,Object[] objArray1){
//TODO: remove NotYetImplementedException and call test steps
throw new NotYetImplementedException();
}

args[0] is used when you have data-driven scenario (scenario with examples) and you want to refer entire record from data provider. In this case as you want to pass map you can try following way:
#test
Scenario: DataTable Examples
Given I am on github login page
And I enter usernames and passwords "{'username':'testuser_1', 'password':'Test#153'}"
Or
#test
Scenario: DataTable Examples
Given I am on github login page
And I enter usernames and passwords
| username | password |
| testuser_1 | Test#153 |
You can refer feature files and step implementation.

Related

Selenium: Best way to test app-features with 2 different users (NUnit, C#)

Im looking for a clean way to test all features on the webpage with 2 different users.
One user is the admin, the second one a normal user.
Here is the overview of my selenium tests:
As you can see, we have 3 different features on the webpage:
UnlockInstruction
Tac
UploadCodes
Each of these features has its own Test class with its own webDriver so im able to run the tests in parallel.
Each of these test files, is calling the Login Class inside the SetUp.
What the Login Class is doing is:
Open Website with goToUrl
Gets the username and password which is stored in a Password Manager tool
Use selenium to enter username, password and click on login
Wait until page after login is loaded and go back to test methods
Everything works perfectly when i test it for one user. All the test run in parallel.
Now i want to test all the same features with the admin user.
The only way which comes into my mind is, to just create another Login class, which gets the other users credentials and copy also the 3 test classes, so all the 6 tests run in parallel.
But in my opinion its not clean, because i would copy 4 files which would have nearly 1:1 the same code.
I'd make the user id and password arguments to the fixtures.
Use a parameterized TestFixture (one with arguments)
Give the same argument types to the constructor so that NUnit can pass them to you.
Your four files will then result in six instances being constructed.
[TestFixture("normalUser", "normalUserPassword")]
[TestFixture("adminUser", "adminUserPassword")]
public class SomeFixture
{
private string User { get; }
private string Password { get; }
public SomeFixture(string user, string password)
{
User = user;
Password = password;
}
[OneTimeSetUp]
public void SetUpTheFixture()
{
// Create the driver
}
...
}
If you prefer to lookup the password, then just make the user id the only argument and look up the password when you need it.
[TestFixture("normalUser")]
[TestFixture("adminUser")]
public class SomeFixture
{
private string User { get; }
public SomeFixture(string user)
{
User = user;
}
[OneTimeSetUp]
public void SetUpTheFixture()
{
// Look up password
// Create driver
}
...
}

Open verification code sent in mail box then copy this code and paste it into verification code field in selenium testing

I am new to selenium web testing i have automated a Sign-In process for a web base application. now making it for Sign Up process i am stuck at a point where a verification code is sent to a mail address and then i have to copy that into my verification code field and proceed further
As i have searched so far i came to know about the mailosaur server but unable to copy that email verification code into my automated web browser. i also searched for the tutorials but unable to find any useful resource. also i want to generate random emails that part is also not getting in my mind.
As i am new to selenium so it is requested to please provide detail answer so i can understand it better, Thanks in advance, working on Intellij, Mavaen (Java)
You can use mailinator.com. No need to register or create a mail box. In your app just enter email with made up name #mailinator.com (asad1#mailinator.com, asadXY#mailinator.com, whatever).
To collect confirmation link (double opt in) I'm using this:
public class Mailinator {
public WebDriver driver;
public Mailinator(WebDriver driver) {this.driver = driver;}
public String urlMailinator = "https://www.mailinator.com/";
public WebDriverWait waitSec(WebDriver driver, int sec) {return new WebDriverWait(driver, sec);}
public static String doubleOptInLink = null;
public String getDoubleOptInLink() {return doubleOptInLink;}
public void setDoubleOptInLink (String doubleOptInLink) {Mailinator.doubleOptInLink = doubleOptInLink;}
public void collectDoubleOptInLink(String userEmail, int expectedNumberOfDeliveredEmails) throws InterruptedException {
driver.get(urlMailinator);
WebElement fldInbox = waitSec(driver, 5).until(ExpectedConditions.elementToBeClickable(By.id("inboxfield")));
fldInbox.sendKeys(userEmail);
WebElement btnGo = driver.findElement(By.xpath("/html/body/section[1]/div/div[3]/div[2]/div[2]/div[1]/span/button"));
btnGo.click();
waitSec(driver, 600).until(ExpectedConditions.numberOfElementsToBe((By.xpath("//*[#id=\"inboxpane\"]/div/div/div/table/tbody/tr")), expectedNumberOfDeliveredEmails));
WebElement lastMailLink = driver.findElement(By.xpath("//*[#id=\"inboxpane\"]/div/div/div/table/tbody/tr"));
lastMailLink.click();
Thread.sleep(3000);
driver.switchTo().frame(driver.findElement(By.id("msg_body")));
setDoubleOptInLink(driver.findElement(By.xpath("//*[#id=\"intro\"]/tbody/tr/td/a")).getAttribute("href"));
}
}
In my scenario:
register to webapp with new made up email, confirmation email is send
using collectDoubleOptInLink(email, 1); is the confirmation link set as doubleOptInLink
calling another method to go to the confirmation link with getDoubleOptInLink();
Sure you will need change what string comes to setDoubleOptInLink();
In specific cases don't forget to setDoubleOptInLink(null);.

how effectively i can use ui automation recorded test cases for other releases of the application

I've web application, I want recorded test cases and play back that cases.
1st release of the application, I've login module which has user name and password and recorded 500 test cases for entire application. Among 500 test cases 200 test cases are using logging by username and password.
2nd release of the application, I've login module which has only username, so I want use previous recorded test cases by modifications not like go to all the test cases change the password field. Here I'm having some requirements for the testing framework
Can I get what are test cases will effect by changing field like in above example?
Is there any way to update in simple, not going like in all the files and changing
I've used different UI Automation testing tools and record & Play back options are very nice, but I could not find the way I want in the UI Automation test framework.
Is there any Framework available which does the job for me?
Thanks in advance.
This is a prime example of why you never should record a selenium test case. Whenever you want to update something like login you have to change them all.
What you should do is create a test harness/framework for your application.
1.Start with creating a class for each webpage with 1 function for each element you want to be able to reach.
public By username(){
return By.cssSelector("input[id$='username']"); }
2.Create helper classes where you create sequences which you use often.
public void login(String username, String password){
items.username().sendkeys(username);
items.password().sendkeys(password);
}
3.In your common test setup add your login function
#BeforeMethod(alwaysRun = true)
public void setUp() {
helper.login("user","password");
}
This give you the opportunity to programmaticly create your test cases. So for example if you want to use the same test cases for a different login module where password element is not present it could be changed like this.
items.username().sendkeys(username);
if(isElementPresent(items.password())
items.password().sendkeys(password);
The function "isElementPresent" could look like this
public boolean isElementPresent(By locator){
try {
driver.findElement(locator);
logger.trace( "Element " + stripBy(locator) + " found");
} catch (NoSuchElementException e) {
logger.trace( "Element " + stripBy(locator) + " not found");
return false;
}
return true;
}

<Cucumber-JVM> pass values between steps in cucumber

How do I pass the values between two steps in cucumber JVM?
In the following scenario, I want to access username provided When step in Then step.
How do I pass the values between two steps in cucumber JVM? Currently I'm accessing those by saving that value into a public variable. Is the approach correct (or) any other way I can access those between the steps?
Scenario:
Given user is on login page
When user enters username as user1 and password as pass1
And clicked on login button
Then post login page is displayed
#When("^user enters username as ([^\"]*) and password as ([^\"]*)$")
public void enterLoginDetails(String username,String password){
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
}
In the following step definition, I want to access username from the previous step definition
#Then("^post login page is displayed$")
public void postLoginValidation(){
// i would like access username and verify username is displayed
}
Thanks in Advance
Best Solution :
If you are using scenario outline:
When user enters username as <username> and password as <password>
Then post login page is displayed with <username>
Examples:
| username|password|
|Kiran|1234|
Step Defination Code:
#When("user enters username as (.*) and password as (.*)")
public void enterLoginDetails(String userName,String password)
{
//You will get userName=Kiran and Password=1234
}
#Then("post login page is displayed with (.*)")
public void postLoginValidation(String userName)
{
//You will be access the same username which is you are passing while login
////You will get userName=Kiran
}
public your class {
private String usr;
#When("^user enters username as ([^\"]*) and password as ([^\"]*)$")
public void enterLoginDetails(String username,String password){
usr = username;
...
}
#Then("^post login page is displayed$")
public void postLoginValidation(){
//do something with usr
}
}
You could share state between steps using variables, as suggested by Bala.
Another solution in Java is to use dependency injection. Cucumber-JVM support many different dependency injection frameworks.
One of them is Spring. Dependencies can be made available where they are needed using annotations. Using Spring is a good option if your project is already using Spring. Otherwise it might be too big and cumbersome.
An easy to use alternative to Spring, is to use PicoContainer.
For more information on either, please have a look at:
http://www.thinkcode.se/blog/2017/06/24/sharing-state-between-steps-in-cucumberjvm-using-spring
http://www.thinkcode.se/blog/2017/04/01/sharing-state-between-steps-in-cucumberjvm-using-picocontainer

Selenium-Webdriver Java: which is the best way to check the validation of lo-gin form

Login page, there would be 3 valid scenarios -
1) valid Login
2) Invalid Login
3) Negative Testing scenario
system is expected to prompt the user with an error message.
But a negative testing scenario would be where you are trying to break the application.
For Instance,
1) leaving Password blank,
2) trying to navigate using the URL,
3) using the forward button of the IE bypassing the Login page etc.....
Using the getting started with selenium [Java] framework, your test would look something like this.
#Config(url="http://systemunder.test", browser=Browser.FIREFOX)
public class TestLogin extends AutomationTest {
#Test
public void testLoginWorks() {
setText(By.id("username"), "valid_username")
.setText(By.id("password"), "valid_password")
.click(By.id("btnLogin"))
.validatePresent(By.id("logout_link"));
}
#Test
public void testPasswordBlank() {
setText(By.id("username"), "invalid_username")
.setText(By.id("password"), "")
.validateText(By.id("error_message"), "Password is blank.");
}
#Test
public void testUrl() {
navigateTo("/profile")
.validateUrl("/login"); // make sure they get redirected to login page.
}
}