quke 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 92924c30819da5865d06a787f986c377541f613d
4
- data.tar.gz: 9924bc07ec76c5573448d76d6e995c7faea1eb15
3
+ metadata.gz: 788a40b36b5d925581baeb7a01057bde80f88c37
4
+ data.tar.gz: 8ff6730baa7ec2a2fd4f02d07759dc2848bd51e1
5
5
  SHA512:
6
- metadata.gz: 93d1b01b7843ea02c2b2d3950d64366813b74d682bab6b8ae302ef6a35784ec0b6fa94fab08cdcd15259ed9789a358200b25a58564a7d184103bc7ae47b1549d
7
- data.tar.gz: c9e70d154ccf11cead106c4d3819ae32ac2bacc2942ee3bd7d35470e25561c15b50fc99f2eaa562450c74f5273214a010370b8ab76371176c5bbfe5cecf66c2e
6
+ metadata.gz: 9fd084be888bc7c7d17fa3fcf3ee2bc3de23c8d735aad227cc8c15d0ed998f8d2631f35504432e3b28e1cb35aa1bebee730ef75556696c3f8f1e196abaefb36a
7
+ data.tar.gz: e7c0d4cf0c1f46c05173d908252cb3ff8714e868d8f6db755372a972804218b78800db70da3b10074b1217231350c17de2e4ee0b80b1a7ee126ca5aac8c2dcf1
data/exe/quke CHANGED
@@ -5,7 +5,5 @@
5
5
  # rubocop:enable Layout/LeadingCommentSpace
6
6
 
7
7
  require "quke"
8
- require "quke/configuration"
9
8
 
10
- Quke::Quke.config = Quke::Configuration.new
11
9
  Quke::Quke.execute(ARGV)
@@ -3,12 +3,15 @@
3
3
  require "rspec/expectations"
4
4
  require "capybara/cucumber"
5
5
  require "site_prism"
6
+ require "quke"
6
7
  require "quke/configuration"
7
8
  require "quke/driver_configuration"
8
9
  require "quke/driver_registration"
9
10
  require "browserstack/local"
10
11
  require "quke/browserstack_status_reporter"
11
12
 
13
+ Quke::Quke.config = Quke::Configuration.new
14
+
12
15
  Capybara.app_host = Quke::Quke.config.app_host unless Quke::Quke.config.app_host.empty?
13
16
 
14
17
  driver_config = Quke::DriverConfiguration.new(Quke::Quke.config)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "selenium/webdriver"
4
4
  require "chromedriver-helper"
5
+ require "byebug"
5
6
 
6
7
  require "quke/version"
7
8
  require "quke/browserstack_configuration"
@@ -25,7 +26,7 @@ module Quke #:nodoc:
25
26
 
26
27
  # The entry point for Quke, it is the one call made by +exe/quke+.
27
28
  def self.execute(args = [])
28
- cuke = CukeRunner.new(@config.features_folder, args)
29
+ cuke = CukeRunner.new(args)
29
30
  cuke.run
30
31
  end
31
32
 
@@ -87,6 +87,21 @@ module Quke #:nodoc:
87
87
  @data["headless"]
88
88
  end
89
89
 
90
+ # Returns the value set for +parallel+.
91
+ #
92
+ # Tells Quke whether run the features in parallel. Depending on the number
93
+ # of cores on the host machine, it will split the features across a given
94
+ # number of processes and run them in parallel.
95
+ #
96
+ # This is great if you have a large test suite (the performance improvement
97
+ # is negligible if you only have a few). However your scenarios must be
98
+ # independent, and the console output will be 'number of processes' *
99
+ # cucumber output. This is best used if you are just after a simple
100
+ # pass/fail result.
101
+ def parallel
102
+ @data["parallel"]
103
+ end
104
+
90
105
  # Return the value set for +pause+.
91
106
  #
92
107
  # Add a pause (in seconds) between steps so you can visually track how the
@@ -197,6 +212,7 @@ module Quke #:nodoc:
197
212
  "app_host" => (data["app_host"] || "").downcase.strip,
198
213
  "driver" => (data["driver"] || "phantomjs").downcase.strip,
199
214
  "headless" => (data["headless"].to_s.downcase.strip == "true"),
215
+ "parallel" => (data["parallel"].to_s.downcase.strip == "true"),
200
216
  "pause" => (data["pause"] || "0").to_s.downcase.strip.to_i,
201
217
  "stop_on_error" => (data["stop_on_error"] || "false").to_s.downcase.strip,
202
218
  "max_wait_time" => (data["max_wait_time"] || Capybara.default_max_wait_time).to_s.downcase.strip.to_i,
@@ -1,19 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cucumber"
4
+ require "parallel_tests"
4
5
 
5
6
  module Quke #:nodoc:
6
7
 
7
8
  # Handles executing Cucumber, including sorting the arguments we pass to it
8
9
  class CukeRunner
9
10
 
10
- # # Access the arguments used by Quke when it was executed
11
+ # Access the arguments used by Quke when it was executed
11
12
  attr_reader :args
12
13
 
13
14
  # When an instance of CukeRunner is initialized it will take the arguments
14
- # passed in and combine them with its own default args.
15
+ # passed in and combine them with its own default args. Those args are a mix
16
+ # of ones specific to ParallelTests, and ones for Cucumber.
15
17
  #
16
- # The default args add the following to the parameters passed to Cucumber
18
+ # In essence we are getting ParallelTests to pass the following to Cucumber
19
+ # along with whatever args are passed in when Quke is called.
17
20
  #
18
21
  # [my_features_folder, '-r', 'lib/features', '-r', my_features_folder]
19
22
  #
@@ -28,33 +31,55 @@ module Quke #:nodoc:
28
31
  # firefox locally
29
32
  # - +-r my_features_folder+, if you specify a different folder for
30
33
  # or wish to test just specific features, you are required by Cucumber
31
- # to also require the folder which contains your steps
32
- # features directory contains the +env.rb+
33
- def initialize(features_folder, args = [])
34
- @args = [
35
- features_folder,
36
- # Because cucumber is called in the context of the executing script it
37
- # will take the next argument from that position, not from where the gem
38
- # currently sits. This means to Cucumber 'lib/features' doesn't exist,
39
- # which means our env.rb never gets loaded. Instead we first have to
40
- # determine where this file is running from when called, then we simply
41
- # replace the last part of that result (which we know will be lib/quke)
42
- # with lib/features. We then pass this full path to Cucumber so it can
43
- # correctly find the folder holding our predefined env.rb file.
44
- "-r", __dir__.sub!("lib/quke", "lib/features"),
45
- "-r", features_folder
46
- ] + args
34
+ # to also require the folder which contains your steps. So we always
35
+ # set this to be sure to handle tagged scenarios, or features run in
36
+ # parallel.
37
+ def initialize(passed_in_args = [])
38
+ Quke.config = Configuration.new
39
+ @args = parallel_args + test_options_args(passed_in_args)
47
40
  end
48
41
 
49
- # Executes Cucumber, passing in the arguments hash set when the instance of
50
- # CukeRunner was created.
42
+ # Executes ParallelTests, which in turn executes Cucumber passing in the
43
+ # arguments defined when the instance of CukeRunner was initialized.
51
44
  def run
52
- Cucumber::Cli::Main.new(@args).execute!
45
+ ParallelTests::CLI.new.run(@args)
53
46
  rescue SystemExit => e
54
47
  # Cucumber calls @kernel.exit() killing your script unless you rescue
55
48
  raise StandardError, "Cucumber exited in a failed state" unless e.success?
56
49
  end
57
50
 
51
+ private
52
+
53
+ def parallel_args
54
+ args = [
55
+ Quke.config.features_folder,
56
+ "--type", "cucumber",
57
+ "--serialize-stdout",
58
+ "--combine-stderr"
59
+ ]
60
+ args += ["--single", "--quiet"] unless Quke.config.parallel
61
+ args
62
+ end
63
+
64
+ def test_options_args(passed_in_args)
65
+ # Because cucumber is called in the context of the executing project and
66
+ # not Quke it will take its arguments in the context of that location, and
67
+ # not from where the Quke currently sits. This means to Cucumber
68
+ # 'lib/features' doesn't exist, which means our env.rb never gets loaded.
69
+ # Instead we first have to determine where this file is running from when
70
+ # called, then we simply replace the last part of that result (which we
71
+ # know will be lib/quke) with lib/features. For example __dir__ returns
72
+ # '/Users/acruikshanks/projects/defra/quke/lib/quke' but we need Cucumber
73
+ # to load '/Users/acruikshanks/projects/defra/quke/lib/features'
74
+ # We then pass this full path to Cucumber so it can correctly find the
75
+ # folder holding our predefined env.rb file.
76
+ env_folder = __dir__.sub!("lib/quke", "lib/features")
77
+ [
78
+ "--test-options",
79
+ "--format pretty -r #{env_folder} -r #{Quke.config.features_folder} #{passed_in_args.join(' ')}"
80
+ ]
81
+ end
82
+
58
83
  end
59
84
 
60
85
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quke #:nodoc:
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -74,6 +74,29 @@ RSpec.describe Quke::Configuration do
74
74
  end
75
75
  end
76
76
 
77
+ describe "#parallel" do
78
+ context "when NOT specified in the config file" do
79
+ it "defaults to false" do
80
+ Quke::Configuration.file_location = data_path(".no_file.yml")
81
+ expect(subject.parallel).to eq(false)
82
+ end
83
+ end
84
+
85
+ context "when specified in the config file" do
86
+ it "matches the config file" do
87
+ Quke::Configuration.file_location = data_path(".parallel.yml")
88
+ expect(subject.parallel).to eq(true)
89
+ end
90
+ end
91
+
92
+ context "when in the config file as a string" do
93
+ it "matches the config file" do
94
+ Quke::Configuration.file_location = data_path(".as_string.yml")
95
+ expect(subject.parallel).to eq(true)
96
+ end
97
+ end
98
+ end
99
+
77
100
  describe "#pause" do
78
101
  context "when NOT specified in the config file" do
79
102
  it "defaults to 0" do
@@ -5,32 +5,23 @@ require "spec_helper"
5
5
  RSpec.describe Quke::CukeRunner do
6
6
  let(:default_args) do
7
7
  features_folder = __dir__.sub!("spec/quke", "lib/features")
8
- ["spec", "-r", features_folder, "-r", "spec"]
8
+ ["features", "--type", "cucumber", "--serialize-stdout", "--combine-stderr", "--single", "--quiet", "--test-options", "--format pretty -r #{features_folder} -r features "]
9
9
  end
10
10
  describe "#initialize" do
11
11
  context "no additional Cucumber arguments passed" do
12
- let(:subject) { Quke::CukeRunner.new("spec") }
12
+ let(:subject) { Quke::CukeRunner.new }
13
13
  it "returns just the default args used by Quke" do
14
14
  expect(subject.args).to eq(default_args)
15
15
  end
16
16
  end
17
17
  context "additional Cucumber arguments passed" do
18
18
  let(:args) { ["--tags", "test"] }
19
- let(:subject) { Quke::CukeRunner.new("spec", args) }
19
+ let!(:subject) { Quke::CukeRunner.new(args) }
20
20
  it "returns the default args plus those passed in" do
21
- expect(subject.args).to eq(default_args + args)
21
+ expected_args = default_args
22
+ expected_args[-1] = expected_args.last + args.join(" ")
23
+ expect(subject.args).to eq(expected_args)
22
24
  end
23
25
  end
24
26
  end
25
-
26
- describe "#run" do
27
- before(:example) do
28
- Quke::Configuration.file_location = data_path(".no_file.yml")
29
- Quke::Quke.config = Quke::Configuration.new
30
- end
31
- let(:subject) { Quke::CukeRunner.new("spec") }
32
- it "does not raise an error when called" do
33
- expect { subject.run }.not_to raise_error
34
- end
35
- end
36
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quke
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Defra
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-27 00:00:00.000000000 Z
11
+ date: 2019-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: parallel_tests
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '2.28'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.28'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: byebug
155
169
  requirement: !ruby/object:Gem::Requirement