diff options
| author | Achilleas Pipinellis <axil@gitlab.com> | 2019-08-20 20:22:43 +0200 |
|---|---|---|
| committer | Achilleas Pipinellis <axil@gitlab.com> | 2019-08-20 20:22:43 +0200 |
| commit | e61308ce1d82e12e5087371469baea4a452875d1 (patch) | |
| tree | 62551a3ae4eab75e5af7e3b35358c07a51b2132f /qa/spec | |
| parent | 4f323bb62fbe71a4352de25cab141f361a3fe1a6 (diff) | |
| parent | 2989ed078c1d45b0959dcecb1bc3c8f4740a3c0d (diff) | |
| download | gitlab-ce-docs-patch-71.tar.gz | |
Merge branch 'master' into docs-patch-71docs-patch-71
Diffstat (limited to 'qa/spec')
| -rw-r--r-- | qa/spec/page/element_spec.rb | 13 | ||||
| -rw-r--r-- | qa/spec/page/logging_spec.rb | 12 | ||||
| -rw-r--r-- | qa/spec/resource/repository/push_spec.rb | 6 | ||||
| -rw-r--r-- | qa/spec/runtime/api/client_spec.rb | 36 | ||||
| -rw-r--r-- | qa/spec/runtime/env_spec.rb | 30 | ||||
| -rw-r--r-- | qa/spec/spec_helper.rb | 6 | ||||
| -rw-r--r-- | qa/spec/specs/parallel_runner_spec.rb | 58 | ||||
| -rw-r--r-- | qa/spec/specs/runner_spec.rb | 76 |
8 files changed, 207 insertions, 30 deletions
diff --git a/qa/spec/page/element_spec.rb b/qa/spec/page/element_spec.rb index f746fe06e40..20d4a00c020 100644 --- a/qa/spec/page/element_spec.rb +++ b/qa/spec/page/element_spec.rb @@ -11,7 +11,7 @@ describe QA::Page::Element do describe '#selector_css' do it 'transforms element name into QA-specific clickable css selector' do expect(described_class.new(:sign_in_button).selector_css) - .to eq '.qa-sign-in-button' + .to include('.qa-sign-in-button') end end @@ -49,6 +49,10 @@ describe QA::Page::Element do it 'does not match if QA selector is not there' do expect(subject.matches?('some_name selector')).to be false end + + it 'matches when element name is specified' do + expect(subject.matches?('data:{qa:{selector:"some_name"}}')).to be true + end end describe 'attributes' do @@ -106,4 +110,11 @@ describe QA::Page::Element do end end end + + describe 'data-qa selectors' do + subject { described_class.new(:my_element) } + it 'properly translates to a data-qa-selector' do + expect(subject.selector_css).to include(%q([data-qa-selector="my_element"])) + end + end end diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb index 092c6a17c9c..92a4f7b40e6 100644 --- a/qa/spec/page/logging_spec.rb +++ b/qa/spec/page/logging_spec.rb @@ -91,26 +91,26 @@ describe QA::Support::Page::Logging do it 'logs has_element?' do expect { subject.has_element?(:element) } - .to output(/has_element\? :element \(wait: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process end it 'logs has_element? with text' do expect { subject.has_element?(:element, text: "some text") } - .to output(/has_element\? :element with text \"some text\" \(wait: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_element\? :element with text \"some text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process end it 'logs has_no_element?' do allow(page).to receive(:has_no_css?).and_return(true) expect { subject.has_no_element?(:element) } - .to output(/has_no_element\? :element \(wait: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process end it 'logs has_no_element? with text' do allow(page).to receive(:has_no_css?).and_return(true) expect { subject.has_no_element?(:element, text: "more text") } - .to output(/has_no_element\? :element with text \"more text\" \(wait: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_no_element\? :element with text \"more text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process end it 'logs has_text?' do @@ -135,9 +135,9 @@ describe QA::Support::Page::Logging do end it 'logs within_element' do - expect { subject.within_element(:element) } + expect { subject.within_element(:element, text: nil) } .to output(/within element :element/).to_stdout_from_any_process - expect { subject.within_element(:element) } + expect { subject.within_element(:element, text: nil) } .to output(/end within element :element/).to_stdout_from_any_process end diff --git a/qa/spec/resource/repository/push_spec.rb b/qa/spec/resource/repository/push_spec.rb index bf3ebce0cfe..2f9e4958ae1 100644 --- a/qa/spec/resource/repository/push_spec.rb +++ b/qa/spec/resource/repository/push_spec.rb @@ -19,7 +19,11 @@ describe QA::Resource::Repository::Push do expect { subject.files = [] }.to raise_error(ArgumentError) end - it 'does not raise if files is an array' do + it 'raises an error if files is not an array of hashes with :name and :content keys' do + expect { subject.files = [{ foo: 'foo' }] }.to raise_error(ArgumentError) + end + + it 'does not raise if files is an array of hashes with :name and :content keys' do expect { subject.files = files }.not_to raise_error end end diff --git a/qa/spec/runtime/api/client_spec.rb b/qa/spec/runtime/api/client_spec.rb index cf19b52700b..6f7020d6595 100644 --- a/qa/spec/runtime/api/client_spec.rb +++ b/qa/spec/runtime/api/client_spec.rb @@ -16,26 +16,56 @@ describe QA::Runtime::API::Client do end describe '#personal_access_token' do - context 'when QA::Runtime::Env.personal_access_token is present' do + context 'when user is nil and QA::Runtime::Env.personal_access_token is present' do before do allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token') end it 'returns specified token from env' do - expect(described_class.new.personal_access_token).to eq 'a_token' + expect(subject.personal_access_token).to eq 'a_token' end end - context 'when QA::Runtime::Env.personal_access_token is nil' do + context 'when user is present and QA::Runtime::Env.personal_access_token is nil' do before do allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil) end it 'returns a created token' do + subject { described_class.new(user: { username: 'foo' }) } + expect(subject).to receive(:create_personal_access_token).and_return('created_token') expect(subject.personal_access_token).to eq 'created_token' end end + + context 'when user is nil and QA::Runtime::Env.personal_access_token is nil' do + before do + allow(QA::Runtime::Env).to receive(:personal_access_token).and_return(nil) + end + + it 'returns a created token' do + client = described_class.new + + expect(client).to receive(:create_personal_access_token).and_return('created_token') + + expect(client.personal_access_token).to eq 'created_token' + end + end + + context 'when user is present and QA::Runtime::Env.personal_access_token is present' do + before do + allow(QA::Runtime::Env).to receive(:personal_access_token).and_return('a_token') + end + + it 'returns a created token' do + client = described_class.new(user: { username: 'foo' }) + + expect(client).to receive(:create_personal_access_token).and_return('created_token') + + expect(client.personal_access_token).to eq 'created_token' + end + end end end diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb index 2560695ef2e..340831aa06d 100644 --- a/qa/spec/runtime/env_spec.rb +++ b/qa/spec/runtime/env_spec.rb @@ -192,6 +192,30 @@ describe QA::Runtime::Env do end end + describe '.knapsack?' do + it 'returns true if KNAPSACK_GENERATE_REPORT is defined' do + stub_env('KNAPSACK_GENERATE_REPORT', 'true') + + expect(described_class.knapsack?).to be_truthy + end + + it 'returns true if KNAPSACK_REPORT_PATH is defined' do + stub_env('KNAPSACK_REPORT_PATH', '/a/path') + + expect(described_class.knapsack?).to be_truthy + end + + it 'returns true if KNAPSACK_TEST_FILE_PATTERN is defined' do + stub_env('KNAPSACK_TEST_FILE_PATTERN', '/a/**/pattern') + + expect(described_class.knapsack?).to be_truthy + end + + it 'returns false if neither KNAPSACK_GENERATE_REPORT nor KNAPSACK_REPORT_PATH nor KNAPSACK_TEST_FILE_PATTERN are defined' do + expect(described_class.knapsack?).to be_falsey + end + end + describe '.require_github_access_token!' do it 'raises ArgumentError if GITHUB_ACCESS_TOKEN is not defined' do stub_env('GITHUB_ACCESS_TOKEN', nil) @@ -227,6 +251,12 @@ describe QA::Runtime::Env do env_key: 'QA_CAN_TEST_GIT_PROTOCOL_V2', default: true + it_behaves_like 'boolean method with parameter', + method: :can_test?, + param: :admin, + env_key: 'QA_CAN_TEST_ADMIN_FEATURES', + default: true + it 'raises ArgumentError if feature is unknown' do expect { described_class.can_test? :foo }.to raise_error(ArgumentError, 'Unknown feature "foo"') end diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index f25dbf3a8ab..363980acc33 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -8,6 +8,10 @@ if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK'] Knapsack::Adapters::RSpecAdapter.bind end +QA::Runtime::Browser.configure! + +QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) if QA::Runtime::Env.runtime_scenario_attributes + %w[helpers shared_examples].each do |d| Dir[::File.join(__dir__, d, '**', '*.rb')].each { |f| require f } end @@ -42,7 +46,7 @@ RSpec.configure do |config| if ENV['CI'] config.around do |example| - retry_times = example.metadata.keys.include?(:quarantine) ? 1 : 2 + retry_times = example.metadata.key?(:quarantine) ? 1 : 2 example.run_with_retry retry: retry_times end end diff --git a/qa/spec/specs/parallel_runner_spec.rb b/qa/spec/specs/parallel_runner_spec.rb new file mode 100644 index 00000000000..67d94a1f648 --- /dev/null +++ b/qa/spec/specs/parallel_runner_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +describe QA::Specs::ParallelRunner do + include Helpers::StubENV + + before do + allow(QA::Runtime::Scenario).to receive(:attributes).and_return(parallel: true) + stub_env('GITLAB_QA_ACCESS_TOKEN', 'skip_token_creation') + end + + it 'passes args to parallel_tests' do + expect_cli_arguments(['--tag', '~orchestrated', *QA::Specs::Runner::DEFAULT_TEST_PATH_ARGS]) + + subject.run(['--tag', '~orchestrated', *QA::Specs::Runner::DEFAULT_TEST_PATH_ARGS]) + end + + it 'passes a given test path to parallel_tests and adds a separator' do + expect_cli_arguments(%w[-- qa/specs/features/foo]) + + subject.run(%w[qa/specs/features/foo]) + end + + it 'passes tags and test paths to parallel_tests and adds a separator' do + expect_cli_arguments(%w[--tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + + subject.run(%w[--tag smoke qa/specs/features/foo qa/specs/features/bar]) + end + + it 'passes tags and test paths with separators to parallel_tests' do + expect_cli_arguments(%w[-- --tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + + subject.run(%w[-- --tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + end + + it 'passes supported environment variables' do + # Test only env vars starting with GITLAB because some of the others + # affect how the runner behaves, and we're not concerned with those + # behaviors in this test + gitlab_env_vars = QA::Runtime::Env::ENV_VARIABLES.reject { |v| !v.start_with?('GITLAB') } + + gitlab_env_vars.each do |k, v| + stub_env(k, v) + end + + gitlab_env_vars['QA_RUNTIME_SCENARIO_ATTRIBUTES'] = '{"parallel":true}' + + expect_cli_arguments([], gitlab_env_vars) + + subject.run([]) + end + + def expect_cli_arguments(arguments, env = { 'QA_RUNTIME_SCENARIO_ATTRIBUTES' => '{"parallel":true}' }) + cmd = "bundle exec parallel_test -t rspec --combine-stderr --serialize-stdout -- #{arguments.join(' ')}" + expect(Open3).to receive(:popen2e) + .with(hash_including(env), cmd) + .and_return(0) + end +end diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb index 5c86c102105..3d98f03a982 100644 --- a/qa/spec/specs/runner_spec.rb +++ b/qa/spec/specs/runner_spec.rb @@ -1,16 +1,22 @@ # frozen_string_literal: true +require 'active_support/core_ext/hash' + describe QA::Specs::Runner do + shared_examples 'excludes orchestrated' do + it 'excludes the orchestrated tag and includes default args' do + expect_rspec_runner_arguments(['--tag', '~orchestrated', *described_class::DEFAULT_TEST_PATH_ARGS]) + + subject.perform + end + end + context '#perform' do before do allow(QA::Runtime::Browser).to receive(:configure!) end - it 'excludes the orchestrated tag by default' do - expect_rspec_runner_arguments(['--tag', '~orchestrated', *described_class::DEFAULT_TEST_PATH_ARGS]) - - subject.perform - end + it_behaves_like 'excludes orchestrated' context 'when tty is set' do subject { described_class.new.tap { |runner| runner.tty = true } } @@ -52,11 +58,11 @@ describe QA::Specs::Runner do end end - context 'when "-- qa/specs/features/foo" is set as options' do - subject { described_class.new.tap { |runner| runner.options = %w[-- qa/specs/features/foo] } } + context 'when "--tag smoke" and "qa/specs/features/foo" are set as options' do + subject { described_class.new.tap { |runner| runner.options = %w[--tag smoke qa/specs/features/foo] } } - it 'passes the given tests path and excludes the orchestrated tag' do - expect_rspec_runner_arguments(['--tag', '~orchestrated', '--', 'qa/specs/features/foo']) + it 'focuses on the given tag and includes the path without excluding the orchestrated tag' do + expect_rspec_runner_arguments(['--tag', 'smoke', 'qa/specs/features/foo']) subject.perform end @@ -67,8 +73,6 @@ describe QA::Specs::Runner do allow(QA::Runtime::Env).to receive(:signup_disabled?).and_return(true) end - subject { described_class.new } - it 'includes default args and excludes the skip_signup_disabled tag' do expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~skip_signup_disabled', *described_class::DEFAULT_TEST_PATH_ARGS]) @@ -76,17 +80,53 @@ describe QA::Specs::Runner do end end - context 'when git protocol v2 is not supported' do - before do - allow(QA::Runtime::Env).to receive(:can_test?).with(:git_protocol_v2).and_return(false) + context 'testable features' do + shared_examples 'one supported feature' do |feature| + before do + QA::Runtime::Env.supported_features.each do |tag, _| + allow(QA::Runtime::Env).to receive(:can_test?).with(tag).and_return(false) + end + + allow(QA::Runtime::Env).to receive(:can_test?).with(feature).and_return(true) unless feature.nil? + end + + it 'includes default args and excludes all unsupported tags' do + expect_rspec_runner_arguments(['--tag', '~orchestrated', *excluded_feature_tags_except(feature), *described_class::DEFAULT_TEST_PATH_ARGS]) + + subject.perform + end end - subject { described_class.new } + context 'when only git protocol 2 is supported' do + it_behaves_like 'one supported feature', :git_protocol_v2 + end - it 'includes default args and excludes the requires_git_protocol_v2 tag' do - expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~requires_git_protocol_v2', *described_class::DEFAULT_TEST_PATH_ARGS]) + context 'when only admin features are supported' do + it_behaves_like 'one supported feature', :admin + end - subject.perform + context 'when no features are supported' do + it_behaves_like 'one supported feature', nil + end + + context 'when all features are supported' do + before do + QA::Runtime::Env.supported_features.each do |tag, _| + allow(QA::Runtime::Env).to receive(:can_test?).with(tag).and_return(true) + end + end + + it_behaves_like 'excludes orchestrated' + end + + context 'when features are not specified' do + it_behaves_like 'excludes orchestrated' + end + end + + def excluded_feature_tags_except(tag) + QA::Runtime::Env.supported_features.except(tag).flat_map do |tag, _| + ['--tag', "~requires_#{tag}"] end end |
