I'm new for Cucumber. While I'm writing a basic feature file I have used tables. and printed the same table values to see how they will display on console. But while printing the values I could see some special characters. What are they and how to remove them? any idea?
I googled to get a solution, but couldn't make it. Can anyone please help me?
Here is my feature file:
Feature: Addding two values
Addding two values
Scenario: tesing sum values
Given input and output
When inputs <inputx> and <inputy> is given
|22|33|
|33|55|
Then output must be <output>
|55|
|88|
And the below is my Ruby File
Given(/^input and output$/) do
puts "Given block"
end
When(/^inputs <inputx> and <inputy> is given$/) do |table|
# table is a Cucumber::Core::Ast::DataTable
puts table
end
Then(/^output must be <output>$/) do |table|
# table is a Cucumber::Core::Ast::DataTable
puts table
end
And the below is the output on the console
*** WARNING: You must use ANSICON 1.31 or higher (https://github.com/adoxa/ansicon/) to get coloured output on Windows
C:/Ruby193/bin/ruby -S bundle exec cucumber --profile default
Using the default profile...
Feature: Addding two values
Addding two values
Scenario: tesing sum values
[32mGiven input and output[0m
[36mGiven block[0m
[32mWhen inputs <inputx> and <inputy> is given[0m
[36m[0m
[36m | [32m 22[0m[0m |[0m [32m 33[0m[0m |[0m[0m
[36m | [32m 33[0m[0m |[0m [32m 55[0m[0m |[0m[0m
| [36m22[0m[0m |[0m [36m33[0m[0m |[0m
| [36m33[0m[0m |[0m [36m55[0m[0m |[0m
[32mThen output must be <output>[0m
[36m[0m
[36m | [32m 55[0m[0m |[0m[0m
[36m | [32m 88[0m[0m |[0m[0m
| [36m55[0m[0m |[0m
| [36m88[0m[0m |[0m
1 scenario ([32m1 passed[0m)
3 steps ([32m3 passed[0m)
0m6.555s
Try adding --no-color to your command line call or your default profile.
For example:
default: --no-source --no-color --format pretty
You are getting this error because cucumber is trying to print the coloured output into the terminal, but your terminal is not able to do so. As a result these symbols are visible. To resolve this issue just add monochrome = true in the Runner (Step Definition) file where you are gluing this cucumber feature file.
Sample Code:
#CucumberOptions(features = {"src/test/resources/FeatureFiles/RegisterUser.feature", "src/test/resources/FeatureFiles/RegisterUserVerifyError.feature"},
glue = "com/assignment2/userreg/stepdefinations/",
tags = {"#multipleverify"}, monochrome = true, plugin = {"pretty", "html:target/cucumber-reports/cucumber-pretty"})
Related
I am able to execute WebUI feature file against single browser (Zalenium) using parallel runner and defined driver in karate-config.js. How can we execute WebUI feature file against multiple browsers (Zalenium) using parallel runner or distributed testing?
Use a Scenario Outline and the parallel runner. Karate will run each row of an Examples table in parallel. But you will have to move the driver config into the Feature.
Just add a parallel runner to this sample project and try: https://github.com/intuit/karate/tree/master/examples/ui-test
Scenario Outline: <type>
* def webUrlBase = karate.properties['web.url.base']
* configure driver = { type: '#(type)', showDriverLog: true }
* driver webUrlBase + '/page-01'
* match text('#placeholder') == 'Before'
* click('{}Click Me')
* match text('#placeholder') == 'After'
Examples:
| type |
| chrome |
| geckodriver |
There are other ways you can experiment with, here is another pattern when you have a normal Scenario in main.feature - which you can then call later from a Scenario Outline from a separate "special" feature - which is used only when you want to do this kind of parallel-ization of UI tests.
Scenario Outline: <config>
* configure driver = config
* call read('main.feature')
Examples:
| config! |
| { type: 'chromedriver' } |
| { type: 'geckodriver' } |
| { type: 'safaridriver' } |
EDIT - also see this answer: https://stackoverflow.com/a/62325328/143475
And for other ideas: https://stackoverflow.com/a/61685169/143475
EDIT - it is possible to re-use the same browser instance for all tests and the Karate CI regression test does this, which is worth studying for ideas: https://stackoverflow.com/a/66762430/143475
I'm reling on community expertise to guide me in the best way about following topic.
In a professional context runing on windows without possibility to install MS-Office application I need to distribut to my team a way to join 2 CSV files and produce a 3rd CSV files as output. Exactly as if we run a SQL query like :
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key
Aims is currently reached with Excel + VBA but MS-office package will be removed and no more accessibly. A solution with MS-Acces is not envisageable because of the same reason.
The goal is to allow any body to actualise the 3rd CSV without any competence and specific installation on it Computer. So an approach with python or MS-SQL-Servr is not good also.
I was thinking to accomplish that with Powshell script but first. I'm not habit to use PowerShell but I can learn.
But before trying that I ask to the community if this is the best way ? Or if there is better solution ? (requirements: Windows OS (latest version), No MS-office, No specific install).
Thank you all.
PowerShell has no built-in join functionality (akin to SQL's[1]) as of v7.2, though adding a Join-Object cmdlet is being proposed in GitHub issue #14994; third-party solutions are available, via the PowerShell Gallery (e.g., JoinModule).
For now, if installing third-party tools isn't an option, you can roll your own solution with the following approach, which usesImport-Csv to load the CSV files, an auxiliary hashtable to find corresponding rows, and Add-Member to add columns (properties).
# Create sample CSV files.
$csv2 = #'
key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3
'# > ./CSVFile1.csv
#'
key,bar
key1,bar1
key2,bar2a
'# > ./CSVFile2.csv
# Import the the 2nd file and load its rows
# (as objects with properties reflecting the columns)
# into a hashtable, keyed by the column 'key' values.
$hash = #{}
foreach ($row in Import-Csv ./CSVFile2.csv) {
$hash[$row.key] = $row
}
# Import the 1st file and process each row (object):
# Look for a matching object from the 2nd file and add
# a calculated column derived from both objects to the
# input object.
Import-Csv ./CSVFile1.csv | ForEach-Object {
$matching = $hash[$_.key]
$_ |
Add-Member -PassThru baz $(if ($matching) { [int] ($matching.bar -eq $_.bar) })
}
Pipe the last statement to Export-Csv to export the resulting objects to a CSV file.
(E.g.
... | Export-Csv -NoTypeInformation -Encoding utf8 Results.csv)
The above yields the following:
key bar quux baz
--- --- ---- ---
key1 bar1 quux1 1
key2 bar2 quux2 0
key3 bar3 quux3
[1] There is a -join operator, but its purpose is to join the elements of a single array to form a single string.
Here's an off the wall answer using the sqlite command-line shell (a single 900kb executable) and the same sql join command. https://sqlite.org/download.html Sqlite seems to have trouble with utf16 or "unicode" text files. Even Excel has more trouble importing a utf16 csv.
# making csv file with ">" (utf16) caused this error:
# CREATE TABLE csvfile1(...) failed: duplicate column name:
'key,bar,quux
key1,bar1,quux1
key2,bar2,quux2
key3,bar3,quux3' | set-content csvfile1.csv
'key,bar
key1,bar1
key2,bar2a' | set-content csvfile2.csv
'.mode csv
.import csvfile1.csv csvfile1
.import csvfile2.csv csvfile2
.headers on
SELECT f1.*, f1.bar = f2.bar as baz
FROM CSVfile1 as f1
LEFT JOIN CSVfile2 as f2
ON f1.key = f2.key' | .\sqlite3
# output
# key,bar,quux,baz
# key1,bar1,quux1,1
# key2,bar2,quux2,0
# key3,bar3,quux3,
I am creating an asciidoc as described below:
Start of document
* R{counter:recom}: sentence1
...
* R{counter:recom}: sentence2
...
* R{counter:recom}: sentence3
End
Note: The R{counter:recom} from the asciidoc will be displayed as R1 R2 R3 in the resulting document.
I need to create a table at the start of the document which will refer the counters and text form the doc as described below:
Start of document
|Ref#|text from the document
|R1|sentence1
|R2|sentence2
|R3|sentence3
throughout the doc:
* R{counter:recom}: sentence1
...
* R{counter:recom}: sentence2
...
* R{counter:recom}: sentence3
End
Now, there are 2 unknown things here:
How do I refer the counter and sentence part from the asciidoc R1 sentence1 in the table together or separately so that, if I change it in the doc it will be changed in the table?
How do I refer the counter values in the table so that they work as links to the actual counter value R1 in the doc?
Not sure there is a readymade construct to achieve this and I haven't figured out how can I achieve it using an anchor or include statement.
What #ahus1 said.
Or, if you can convert your counter lines into section titles, then it's easy:
= Document
[cols="a"]
|===
| <<first>>
| <<second>>
| <<third>>
|===
...
[[first]]
== R{counter:recom}: sentence 1
...
[[second]]
== R{counter:recom}: sentence 2
...
[[third]]
== R{counter:recom}: sentence 3
...
End
The following is an experiment with attributes. It fulfills the following requirements:
if you change the sentence in the attribute, it will be changed in both the table and the doc
the table and the doc will contain the same number
the table to the item in the document
:ref-a: R{counter:recom}
:sen-a: sentence1
:ref-b: R{counter:recom}
:sen-b: sentence2
:ref-c: R{counter:recom}
:sen-c: sentence3
|===
|Ref#|text from the document
|<<link-a>>|{sen-a}
|<<link-b>>|{sen-b}
|<<link-c>>|{sen-c}
|===
throughout the doc:
* [[link-a,{ref-a}]]{ref-a}: {sen-a}
...
* [[link-b,{ref-b}]]{ref-b}: {sen-b}
...
* [[link-c,{ref-c}]]{ref-c}: {sen-c}
...
rendering this with either
Asciidoctor 2.0.10 [https://asciidoctor.org]
Runtime Environment (jruby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 Java HotSpot(TM) 64-Bit Server VM 25.161-b12 on 1.8.0_161-b12 +jit [mswin32-x86_64]) (lc:CP850 fs:Windows-1252 in:CP850 ex:CP850)
or
Asciidoctor PDF 1.5.0.beta.1 using Asciidoctor 2.0.10 [https://asciidoctor.org]
Runtime Environment (jruby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 Java HotSpot(TM) 64-Bit Server VM 25.161-b12 on 1.8.0_161-b12 +jit [mswin32-x86_64]) (lc:CP850 fs:Windows-1252 in:CP850 ex:CP850)
displays
Alternative to putting the sentence in an attribute: assuming that each chapter is described in a separate file, you can use an include statement that only includes the first line of the file for the table using include::filename.txt[lines=1], and later include the full file inside the document. See Include By Line Ranges in the Asciidoctor documentation for details (you can also use tags to specify the contents for the table).
This step in my Ruby feature file to find and access a customer record:
When I search with the following details: "<recordReference>", "<secondIdentifier>", "<postcode>":
| recordReference | secondIdentifier| postcode |
| REFABCDE12345678| IDcode1234 | PC11 1PC |
It has this step definition:
When(/^I search with the following details: "(.*?)", "(.*?)", "(.*?)":$/) do |recordReference, secondIdentifier, postcode|
find(:css, "#dln").native.send_keys recordReference
find(:css, "#nino").native.send_keys secondIdentifier
find(:css, "#postcode").native.send_keys postcode
check 'confirmation'
click_button 'submit'
end
When it's run, I get the following error:
Cucumber::ArityMismatchError: Your block takes 3 arguments, but the Regexp matched 4 arguments.
features/step_definitions/refactored_commands.rb:207:in `/^I search with the following details: "(.*?)", "(.*?)", "(.*?)":$/'
What have I done wrong and how can it be fixed?
For info - I get the same error message if the parenthases are take out of the step definition:
When /^I search with the following details: "(.*?)", "(.*?)", "(.*?)":$/ do |recordReference, secondIdentifier, postcode|
The fourth argument is the DataTable. Remove the first 3 parameters and put in just the DataTable option, you will get all the data from the DataTable. Suggest you use dryRun=true option to let Cucumber create the proper step definition matcher, this is from my Java knowledge dont know how this dryRun option is in ruby.
Plus you will have to change your step in the feature file to remove the mentioned 3 parameters
It looks like you're mixing up scenario outlines with passing data tables to steps
From the format of your table it looks like what you're going for should actually be
Scenario Outline: xxx
...
When I search with the following details: "<recordReference>", "<secondIdentifier>", "<postcode>"
...
Examples:
| recordReference | secondIdentifier| postcode |
| REFABCDE12345678| IDcode1234 | PC11 1PC |
and then each the outline will be called once for each row of Examples with the values filled in - so your step would be
When(/^I search with the following details: "(.*?)", "(.*?)", "(.*?)"$/) do |recordReference, secondIdentifier, postcode|
...
end
On a side note - is there any reason you're calling .native.send_keys - I believe every driver now supports the normal Capybara send_keys API so it would just be find(:css, '#dln').send_keys recordReference (or of course just fill_in('dln', with: recordReference) )
The exception I am getting is "ActiveRecord::ConnectionNotEstablished: No connection pool for ActiveRecord::Base". I am really on the deep end of the pool (no pun intended) with this one. I really don't understand the connection and connection pool handling, even as much as I have studied this problem. I'm assuming this might be scope related inside of Cucumber, but I do not know. Any and all assistance is appreciated.
Here are the details:
The exception occurs when I perform a count from a Then clause:
WorkTable.where('? is not null',col['COLUMN_NAME']).count
It does not occur if I send the sql directly through the connection:
WorkTable.connection.select_all(st.encode('utf-8')).first['nulls']
My scenario reads as follows:
Scenario: CompanyMaster test for null value
Given table dbo.base_table in stage
Then these columns are expected to be not null
| COLUMN_NAME | nulls |
| id | 0 |
| company_name | 0 |
I establish my class in my env.rb:
class WorkTable < ActiveRecord::Base
end
ActiveRecord::Base.configurations = YAML.load_file(yaml) # yaml is database.yml file name
I establish my connection in a Given clause:
Given(/^table (\w+)\.?([\w_]+) in (\w+)(?: as (\w+))?$/) do |schema,name,env,id|
#sc_name = schema_file_name(schema,name)
WorkTable.logger.info title_line("* Active table(#{#sc_name}) *")
case id
# ActiveRecord::Base.configurations[env]
...
else
WorkTable.table_name = #sc_name
WorkTable.establish_connection(env.to_sym)
# ary = get_tables(WorkTable,schema:schema)
# expect( ary.any?{|s| s.casecmp(name)==0 } ).to eq(true)
end
end
I execute my test in a Then clause:
Then(/^these columns are expected to be not null$/) do |columns|
# expected is an instance of Cucumber::Ast::Table
WorkTable.logger.info title_line('Columns cannot be null')
results = []
columns.hashes.each {|col|
results << {
'COLUMN_NAME' => col['COLUMN_NAME'],
'nulls' => WorkTable.where('? is not null',col['COLUMN_NAME']).count.to_s
}
}
columns.diff!(results,surplus_row: false)
end
It is the WorkTable.where that throws the "ActiveRecord::ConnectionNotEstablished: No connection pool for ActiveRecord::Base". Again, if I use the WorkTable.connection method, I do not get it. Also, it executes fine if I copy all the function code to single ruby script.
I see the following when I "pp WorkTable.connection":
#<ActiveRecord::ConnectionAdapters::SQLServerAdapter version: 4.2.2, mode: dblib, azure: false>
And I see the following when I "pp WorkTable.connection_pool":
#<ActiveRecord::ConnectionAdapters::ConnectionPool:0x42f5238
#automatic_reconnect=true,
#available=
#<ActiveRecord::ConnectionAdapters::ConnectionPool::Queue:0x42f4f20
#cond=
#<MonitorMixin::ConditionVariable:0x42f4ed8
#cond=
#<ConditionVariable:0x42f4de8
#waiters=[],
#waiters_mutex=#<Mutex:0x42f4d58>>,
#monitor=
#<ActiveRecord::ConnectionAdapters::ConnectionPool:0x42f5238 ...>>,
#lock=#<ActiveRecord::ConnectionAdapters::ConnectionPool:0x42f5238 ...>,
#num_waiting=0,
#queue=[]>,
#checkout_timeout=5,
#connections=
[#<ActiveRecord::ConnectionAdapters::SQLServerAdapter version: 4.2.2, mode: dblib, azure: false>],
#mon_count=0,
#mon_mutex=#<Mutex:0x42f51c0>,
#mon_owner=nil,
#reaper=
#<ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper:0x42f51a8
#frequency=nil,
#pool=#<ActiveRecord::ConnectionAdapters::ConnectionPool:0x42f5238 ...>>,
#reserved_connections=
#<ThreadSafe::Cache:0x42f4fc8
#backend=
{16931712=>
#<ActiveRecord::ConnectionAdapters::SQLServerAdapter version: 4.2.2, mode: dblib, azure: false>},
#default_proc=nil>,
#size=5,
#spec=
#<ActiveRecord::ConnectionAdapters::ConnectionSpecification:0x42f55c8
#adapter_method="sqlserver_connection",
#config=
{:host=>"server_name",
:database=>"mssb_stg",
:encoding=>"utf-8",
:adapter=>"sqlserver",
:timeout=>5000}>>
Ruby 1.9.3, activerecord (4.2.0), activerecord-sqlserver-adapter (4.2.2), and cucumber (1.3.18). And sql server 2014 [this has been a bugger for me].
Thank you for you time and consideration.
dvn
== Additional detail ==
Ignore the sql-server reference. I get the same exception when I reconfigure to work with SqLite. So it is not related to db platform.
Check your env.rb, conf in supports, it seems you are making connections in steps, ideally you should do it in before_scenario or before feature file rather than per steps.
It could be possible after steps your connection is not working properly.