Undefined dynamic step - Table inside a step reference for cucumber - ruby

I have the following situation here. A hypothetical .feature file has this:
Scenario Outline: Test
Given bla bla bla
When I input the <data>
Then I should see a message
Examples:
| data |
| test1 |
| test2 |
And I need to execute the "I input the " on a step reference.
So I have this:
Given('I already have data') do
step %{input the <data>
| data |
| test1 |
| test2 |
}
end
And its giving me the "Undefined dynamic step" error. What should I do in this case, to get it working?
Thanks a lot!

Related

Stop godog from parsing Scenario Outline example data table rows

I am not sure it this is intended to be so, but I am confused by the behavior.
When I have the following Scenario Outline:
Scenario Outline: outline1
Given url
And query parameters <query_params>
When method
Then status is
Examples:
| method | endpoint | query_params | status |
| GET | /endpoint1 | ?a=1&b=1 | 200 |
| GET | /endpoint1 | ?a=1&b=1&c=3 | 200 |
I see the following snippet generated.
func FeatureContext(s *godog.Suite) {
s.Step(^method GET$, methodGET)
s.Step(^query parameters \?a=(\d+)&b=(\d+)$, queryParametersAB)
s.Step(^query parameters \?a=(\d+)&b=(\d+)&c=(\d+)$, queryParametersABC)
}
As you can see 2 lines of "query parameters" produces 2 different functions. Why is godog parsing this text? This is a little different from cucumber gherkin parsing.
One side effect of this is that if I have 100 lines in the data table, I am forced to implement all of them.
Is there a way I can ask godog to not do this parsing?
The solution to the problem is to use double quotes around as given below.
Scenario Outline: outline1
Given url
And query parameters "<query_params>"
When method
Then status is
Examples:
| method | endpoint | query_params | status |
| GET | /endpoint1 | ?a=1&b=1 | 200 |
| GET | /endpoint1 | ?a=1&b=1&c=3 | 200 |
Then the following will be generated:
s.Step(`^query parameters "([^"]*)"$`, queryParameters)

Data Driven Testing Nightwatch

I am currently working on deciding a tool for automation an app on react/redux platform.
Most of the scenarios that I have in the app is possible to automate using nightwatch.
There are certain test cases or scenarios which repeat itself for different data sets.
For eg.
Steps to be executed:
Login to the application
Enter search criteria Step
Enter Color 1, Color 2, Color 3
Save and Validate
Test Data:
|UserName|Password|Search Criteria|Color 1|Color 2|Color 3|
-----------------------------------------------------------------------------
|abc | abc | search 1 |red | | |
|abc | abc | search 1 | |green | |
|abc | abc | search 2 |grey |white | |
|abc | abc | search 3 |white |black | yellow|
I have to execute the same set of code/steps multiple times depending the number of rows of test data we have.
I tried reading a lot of documentations but could not find any package which supports this type of automation in nightwatch.
Please help. Please do let me know if you need any more information.
Thanks & Regards,
Mukesh Panda
My suggestion is to place the test data in a JSON file and read it in your testpage file. and call it from testfile. something like,
loginPage.js contains
setCredentials : function (username, password) {
browser.setValue('#username', username);
browser.setValue('#password', password);
}
module.exports=loginPage;
and call the function in your test file like
loginTest.js contains
testData = require('testData.json');
loginPage = require('loginPage.js');
login = new loginPage(browser);
login.setCredentials(testData.username, testData.password);
something like this you can achieve it...

How write table inside of cucumber step with table

I'm writing scenarios for QA engineers, and now I face a problem such as step encapsulation.
This is my scenario:
When I open connection
And device are ready to receive files
I send to device file with params:
| name | ololo |
| type | txt |
| size | 123 |
All of each steps are important for people, who will use my steps.
And I need to automate this steps and repeat it 100 times.
So I decide create new step, which run it 100 times.
First variant was to create step with other steps inside like:
Then I open connection, check device are ready and send file with params 100 times:
| name | ololo |
| type | txt |
| size | 123 |
But this version is not appropriate, because:
people who will use it, will don't understand which steps executes inside
and some times name of steps like this are to long
Second variant was to create step with other steps in parameters table:
I execute following steps 100 times:
| When I open connection |
| And device are ready to receive files |
| I send to device file |
It will be easy to understand for people, who will use me steps and scenarios.
But also I have some steps with parameters,
and I need to create something like two tier table:
I execute following steps 100 times:
| When I open connection |
| And device are ready to receive files |
| I send to device file with params: |
| | name | ololo | |
| | type | txt | |
| | size | 123 | |
This is the best variant in my situation.
But of cause cucumber can't parse it without errors ( it's not correct as cucumber code ).
How can I fix last example of step? (mark with bold font)
Does cucumber have some instruments, which helps me?
Can you suggest some suggest your type of solution?
Does someone have similar problems?
I decide to change symbols "|" to "/" in parameters table, which are inside.
It's not perfect, but it works:
This is scenarios steps:
I execute following steps 100 times:
| I open connection |
| device are ready to receive files |
| I send to device file with params: |
| / name / ololo / |
| / type / txt / |
| / size / 123 / |
This is step definition:
And /^I execute following steps (.*) times:$/ do |number, table|
data = table.raw.map{ |raw| raw.last }
number.to_i.times do
params = []
step_name = ''
data.each_with_index do |line,index|
next_is_not_param = data[index+1].nil? || ( data[index+1] && !data[index+1].include?('/') )
if !line.include?('/')
step_name = line
#p step_name if next_is_not_param
step step_name if next_is_not_param
else
params += [line.gsub('/','|')]
if next_is_not_param
step_table = Cucumber::Ast::Table.parse( params.join("\n"), nil, nil )
#p step_name
#p step_table
step step_name, step_table
params = []
end
end
end
#p '---------------------------------------------------------'
end
end

Cucumber: Multiline arguments using "step" method inside a step definition

The factory_girl Cucumber helpers are cool. I love that this works:
Given the following users exist:
| Name | Email |
| Alan | alan#example.com |
| Bob | bob#example.com |
But I can't work out how to invoke them inside a step definition. For instance:
Given /the usual users exist/ do
step "the following users exist:
| Name | Email |
| Alan | alan#example.com |
| Bob | bob#example.com |"
end
... throws Your block takes 1 argument, but the Regexp matched 0 arguments. (Cucumber::ArityMismatchError).
What's the correct way to pass a multiline argument to another step using step inside a step definition?
Edit:
Source code's always handy. I found that the signature for step is def step(name, multiline_argument=nil). Suggestive. Sadly, however,
step "the following users exist", "
| Name | Email |
| Alan | alan#example.com |
| Bob | bob#example.com |"
also fails with undefined method 'hashes' for #<Cucumber::Ast::DocString:0xa9bf6f4> (NoMethodError). I'd still love to know how that's supposed to work.
However, there's a silver lining. I found another function steps, which is def steps(steps_text), and that works. See answer.
It's not quite what I was looking for, but reading the source code reveals that the following works:
Given /the usual users exist/ do
steps "Given the following users exist:
| Name | Email |
| Alan | alan#example.com |
| Bob | bob#example.com |"
end

How do I use regular expressions in a Cucumber table (multiline argument) to diff against table?

I am using a scenario table (multiline step arguments) to check some data from a screen using cucumber, using the in built .diff! method on the Cucumber AST table.
I would like to check the content matches against regular expressions.
Scenario: One
Then the table appears as:
| One | Two | Three |
| /\d+/ | /\d+/ | /\d+/ |
The actual table could look something like
| One | Two | Three |
| 123 | 456 | 789 |
which this scenario is translated to "as long as there are some digits, I don't care"
An example step implementation that fails:
Then /^the table appears as:$/ do |expected_table|
actual_table = [['One','Two', 'Three'],['123', '456', '789']]
expected_table.diff! actual_table
end
Error:
Then the table appears as: # features/step_definitions/my_steps.rb:230
| One | Two | Three |
| /\\d+/ | /\\d+/ | /\\d+/ |
| 123 | 456 | 789 |
Tables were not identical (Cucumber::Ast::Table::Different)
I have tried using step transforms to transform the cells into regular expressions, but they still aren't identical.
Transform code:
expected_table.raw[0].each do |column|
expected_table.map_column! column do |cell|
if cell.respond_to? :start_with?
if cell.start_with? "/"
cell.to_regexp
else
cell
end
else
cell
end
end
end
which provides the eror:
Then the table appears as: # features/step_definitions/my_steps.rb:228
| One | Two | Three |
| (?-mix:\\d+) | (?-mix:\\d+) | (?-mix:\\d+) |
| 123 | 456 | 789 |
Tables were not identical (Cucumber::Ast::Table::Different)
Any ideas? I am stuck.
Using regular expressions in a scenario is almost certainly the wrong approach. Cucumber features are intended to be read and understood by business-focussed stakeholders.
How about writing the step at a higher level, such as as:
Then the first three columns of the table should contain a digit
There is no way to do it without writing your own implementation of diff! method from Ast::Table. Take a look into cucumber/lib/ast/table.rb. Internally it uses diff-lcs library to do an actual comparison which doesn't support regex match.
It seems that you want to write this in a way that provides the cool diff output. Otherwise, I'd look at writing this such that you simply check the rows. It won't be as pretty, and it won't get you the diff of the entire table, but it's something.
Then /^the table appears as:$/ do |expected_table|
actual_table = [['One','Two', 'Three'],['123', '456', '789']]
expected_table.raw.each_with_index { |row, y|
row.each_with_index { |cell, x|
actual_table[x][y].should == cell
}
}
end

Resources