Testng assert with DataProvider object values - selenium

i create a function test false login test but i want to assert with those loop test
here is my sample data
#DataProvider(name = "Lgindataprovides")
public Object[][] getData(){
Object[][] data= {
{"abcd#mail.com","12345666"}#email and password wrong (asset text = enter email is not available please register)
{"xyz#mail.com","12345666"},#email correct password wrong (assert text = password is wrong)
return data;
}
here is my test
#Test(dataProvider = "Lgindataprovides", dependsOnMethods = "boofoo")
public void logintest(String email, String passowrd) {
driver.get("https://dummyurl/login");
driver.findElement(By.id("email")).sendKeys(email);
driver.findElement(By.id("password")).sendKeys(passowrd);
driver.findElement(By.cssSelector("button[type='submit']"));
Assert.assertEquals(get1stdatatest, "enter email is not available please register")
Assert.assertEquals(get2nderrordatatest, "password is wrong")
}
buts it fails this test case how can I handle this?
what I want is
when this data"abcd#mail.com","12345666" is passed to the login test its should assert with this "enter email is not available please register"
when this dataxyz#mail.com","12345666 is passed to the login test its should assert with this "enter email is not available please register"

I see, you wand to check a unique error message per test data pair.
Add the 3rd item to data-provider with the error message text you expecting. So, each email/password will be linked with the error message.
#DataProvider(name = "Lgindataprovides")
public Object[][] getData(){
Object[][] data= {
{"abcd#mail.com","12345666", "error-message-1"},
{"xyz#mail.com","12345666", "error-message-2"}
}
return data;
}
Add 3rd arg to your test and assert that actual error matches the expected.
#Test(dataProvider = "Lgindataprovides", dependsOnMethods = "boofoo")
public void logintest(String email, String passowrd, String expectedError) {
driver.get("https://dummyurl/login");
driver.findElement(By.id("email")).sendKeys(email);
driver.findElement(By.id("password")).sendKeys(passowrd);
driver.findElement(By.cssSelector("button[type='submit']"));
Assert.assertEquals(getActualErrorMessage(driver), expectedError)
}
Adjust the method which getting the actual error message text. Your locator for driver.findElement sould find both password or email error messages. You might try to use xpath and search by some class //*[contains(#class, 'some-error-class']. So, you'll get any error message text on the form and it should work.
private String getActualErrorMessage(WebDriver driver) {
driver.findElement(By.xpath("...")).getText();
}
You might also do it inline without creating a new method. Also add some waits/timeouts if you need.

Related

is there a way to pass data directly in Step definition without passing in feature file?

i want to use dataprovider to pass data directly into step definition without passing from feature file, as i want to pass null values as well. here is what i am doing.
Scenario: User should get empty field highlight, when that fields is empty and clicked submit. When Submit is clicked after providing values in nethier or either of Reg Id or PC
#Test(dataProvider = "getData")
#When("^Submit is clicked after providing values in nethier or either of Reg Id or PC$")
public void submit_is_clicked_after_providing_values_in_nethier_or_either_of_reg_id_something_or_pc_something(
String regvalue, String pcvalue) throws Throwable {
//code
}
#DataProvider
public Object[][] getData() {
Object[][] data = new Object[3][2]; // 3 is number of combinations and 2 is number of values
// 1st set
data[0][0] = "Username1";
data[0][1] = null;
// 2nd set
data[1][0] = null;
data[1][1] = "Password1";
// 3nd set
data[2][0] = null;
data[2][1] = null;
return data;
}
Error i am getting is
Step [^Submit is clicked after providing values in nethier or either of Reg Id or PC$] is defined with 2 parameters at 'com.commcard.stepdefinition.StepDef.submit_is_clicked_after_providing_values_in_nethier_or_either_of_reg_id_something_or_pc_something(String,String) in file:/D:/Eclipse-Workspace/CucumberProject.CitiCommCard/target/test-classes/'.
However, the gherkin step has 0 arguments.
You can use a yml file as a data-lookup. For JSON style testing I would advocate this. As you can use a regular fixture or build it up mid-process.
So you could have something like this.
Given I have a valid request to create a user
But the username is invalid
Given I have a valid request to create a user
But the username is too short
# yaml file
user:
create:
issues:
username:
invalid: "Can't Use W3!rd char$"
too_short: "usrnm"
Then your steps just use whatever programming language you use and convert the yml into a data lookup (Hash/List), and alter the keys.

How to use data from scenario one into another using Cucumber and RestAssured

I am doing API automation using Cucumber and RestAssured.
I have a feature file having 2 scenarios.
On successful execution of Scenario 1 cookies are getting generated. I want to use these cookies as authorization is scenario 2. Can some 1 suggest me a way to do so?
Here is my Feature File look like :
Scenario1: Verify SignUp with Valid Email Address
Given SignUp Payload with Email "New"
When User Calls SignUp API with PUT request
Then API call is success with status code 200
And "status.status_type" in response body as "true"
And "status.status_message" in response body as "Request Successful"
And "item.has_signup" in response body as "true"
Scenario2: Verify SignUp for already signedUp user
Given SignUp Payload with Email "New1"
When User Calls SignUp API with PUT request
Then API call is success with status code 200
And "status.status_type" in response body as "false"
And "status.status_message" in response body as "Looks, like you have used different email address before. Please login with original email address you used to create an account."
Here is how my test File look Like :
public class signUp {
ResponseSpecification response_spec;
RequestSpecification request;
Response response;
TestData data = new TestData();
String ia_uid_cookie;
String ia_jwt_cookie;
#Given("SignUp Payload with Email {string}")
public void signup_Payload_with_Email(String userEmail) throws IOException{
response_spec = new ResponseSpecBuilder().expectStatusCode(200).expectContentType(ContentType.JSON).build();
if(userEmail.equals("New") ){
request = RestAssured.given().spec(requestSpecs()).body(data.signUpPayload());
}
else if (userEmail.equals("New1")) {
request = RestAssured.given().spec(requestSpecs()).cookies("_ia_jwt", ia_jwt_cookie, "_ia_uid", ia_uid_cookie).body(data.signUpPayload());
}
else{
request = RestAssured.given().spec(requestSpecs()).body(data.emptyPayload());
}
}
#When("User Calls SignUp API with PUT request")
public void user_Calls_SignUp_API_with_PUT_request() throws IOException {
response = request.when().put(getGlobalValue("signup_uri")).then()
.spec(response_spec).extract().response();
Map<String, String> userCookies = response.getCookies();
ia_uid_cookie= userCookies.get("_ia_uid");
ia_jwt_cookie= userCookies.get("_ia_jwt");
}
#Then("API call is success with status code {int}")
public void api_call_is_success_with_status_code(Integer int1) {
assertEquals(response.getStatusCode(),200);
}
#Then("{string} in response body as {string}")
public void in_response_body_as(String actual, String expected) {
JsonPath resp_string = responseInString(response);
assertEquals(resp_string.get(actual).toString(), expected);
}
}
Use dependency injection using any DI containers
https://www.toolsqa.com/selenium-cucumber-framework/share-data-between-steps-in-cucumber-using-scenario-context/

TestNG DataProvider marks as invalid return type Iterator<CustomObject>, but it passes the params into a test method

When creating a Dataprovider that returns Iterator I have it in my test method, but my intellij-idea marks this return type as invalid and shows the message:
"Data provider must return either Object[][] or Iterator[], or Iterator".
Here is my class/ method:
public class TradeTestDataProvider {
#DataProvider(name = "experimental")
public Iterator<TestCase> createCases() throws IOException {
List<TestCase> test = DataReader.generateCasesFromJson("src/test/resources/json/experimental_test_case");
return test.iterator();
}
}
Please advise, if I am missing something or it is related to TestNG/IDE issue?
Update:
I created a post to discuss this issue with plugin:
topic

Spring Shell - capturing user input in middle of executing ShellMethod

Is the a way to capture user input in middle of executing #ShellMethod. Basically stoping executing of the method to ask for the user input and carrying on after capturing it.
There is possible solution here: https://stackoverflow.com/a/50954716, authored by ZachOfAllTrades
It works only when your app is SpringBoot-based, so you'll have access to the LineReader object, configured by SpringBoot.
#Autowired
LineReader reader;
public String ask(String question) {
return this.reader.readLine("\n" + question + " > ");
}
#ShellMethod(key = { "setService", "select" }, value = "Choose a Speech to Text Service")
public void setService() {
boolean success = false;
do {
String question = "Please select a service.";
// Get Input
String input = this.ask(question);
// Input handling
/*
* do something with input variable
*/
success = true;
}
} while (!success);
}
I didn't try it myself, though.
Use Spring Shell UI Components, now that we're in the future.
"Starting from 2.1.x there is a new component model which provides easier way to create higher level user interaction for usual use cases like asking input in a various forms. These usually are just plain text input or choosing something from a list."
#ShellComponent
public class ComponentCommands extends AbstractShellComponent {
#ShellMethod(key = "component string", value = "String input", group = "Components")
public String stringInput(boolean mask) {
StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue");
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
if (mask) {
component.setMaskCharater('*');
}
StringInputContext context = component.run(StringInputContext.empty());
return "Got value " + context.getResultValue();
}
}
https://docs.spring.io/spring-shell/docs/2.1.0-SNAPSHOT/site/reference/htmlsingle/#_build_in_components
You should be able to interact directly with System.in although it is not really what Spring Shell is about: commands should be self contained.

Selenium valid Email test case

I have started writting test cases for a project, The first page is login page.
i have started to write test case for valid email adress validation.
public void LoginValidEmailProvided(string baseUrl)
{
_driver.Navigate().GoToUrl(baseUrl);
UserIdField.Clear();
UserIdField.SendKeys("abc.xyz.com");
PasswordField.Clear();
PasswordField.SendKeys("");
LoginButton.Click();
}
Now my question is do we need to write different function for each variation for valid emaiil address checking.
Like on manual testing test usually do
some.com
#some.com
#some
some#
some###.com
and many more.
so do we have to write test cases for above varaitions in automate testing. or just one variation is suffucient. as I am checking the return message and comparing with expected and what I get. In each case it returns Invalid credentials. So I have just checked is page contains the message Invalid credentials then the Invalid Emaild address test case passed.
Please advise
Thanks
The better approach would be have two methods one to check valid email address and other to check invalid email address
Advantages of having two methods
You can have valid credentials seperately in a file or a data provider(incase of frameworks) and pass valid credentials only to the check valid_email method and invalid credentials to invalid_email method so that if there is any error you can locate it easily(ex : valid credentials is throwing an error saying that the credentials in invalid) if you combine both the credentials then it will be difficult for you to find which is valid and which is invalid
pseudecode :
public void correct_email(){
enter username and other details
click submit
Get the success page or page title of homepage to check email validation passed
}
public void wrong_email(){
enter username and other details
click submit
Get the error page and compare it with the actual error message
}
EDIT :
1.If you're keeping your valid and invalid credentials together and having one method to validate it how do you know if a valid login credentials failed to login it will also throw an error invalid credentials and you're test will pass and you will not notice this error
2.Moreover if you're using frameworks like ex: testng you will get these data in reports if ur parameterizing your tests so in reports also it gives you a clear view of data passed and failed ie)Parameters run using valid credentials and parameters run using invalid credentials .if you use one method to validate vaiid and invalid credentials all will be listed as one.
Hope this helps you.Kindly get back if you have any queries
Do not create a different method you can use data provider for each test !!!
(you can write a rapper that the data provider will look nicer )
http://testng.org/doc/documentation-main.html
//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
#DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
{ "Cedric", new Integer(36) },
{ "Anne", new Integer(37)},
};
}
//This test method declares that its data should be supplied by the Data Provider
//named "test1"
#Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
System.out.println(n1 + " " + n2);
}
will print
Cedric 36
Anne 37