diff options
Diffstat (limited to 'qa')
28 files changed, 283 insertions, 133 deletions
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index 1bc424335f8..8f523e55adc 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -77,7 +77,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.0) - rubyzip (1.2.1) + rubyzip (1.2.2) selenium-webdriver (3.8.0) childprocess (~> 0.5) rubyzip (~> 1.0) @@ -103,4 +103,4 @@ DEPENDENCIES selenium-webdriver (~> 3.8.0) BUNDLED WITH - 1.16.1 + 1.16.4 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $: << File.expand_path(File.dirname(__FILE__)) Encoding.default_external = 'UTF-8' @@ -98,6 +100,7 @@ module QA end module Sanity + autoload :Failing, 'qa/scenario/test/sanity/failing' autoload :Selectors, 'qa/scenario/test/sanity/selectors' end end @@ -212,10 +215,6 @@ module QA end end - module Shared - autoload :ClonePanel, 'qa/page/shared/clone_panel' - end - module Profile autoload :PersonalAccessTokens, 'qa/page/profile/personal_access_tokens' end @@ -249,7 +248,9 @@ module QA # Classes describing components that are used by several pages. # module Component + autoload :ClonePanel, 'qa/page/component/clone_panel' autoload :Dropzone, 'qa/page/component/dropzone' + autoload :GroupsFilter, 'qa/page/component/groups_filter' autoload :Select2, 'qa/page/component/select2' end end diff --git a/qa/qa/factory/resource/group.rb b/qa/qa/factory/resource/group.rb index 531fccd2ad8..033fc48c08f 100644 --- a/qa/qa/factory/resource/group.rb +++ b/qa/qa/factory/resource/group.rb @@ -2,7 +2,7 @@ module QA module Factory module Resource class Group < Factory::Base - attr_writer :path, :description + attr_accessor :path, :description dependency Factory::Resource::Sandbox, as: :sandbox @@ -14,17 +14,23 @@ module QA def fabricate! sandbox.visit! - Page::Group::Show.perform do |page| - if page.has_subgroup?(@path) - page.go_to_subgroup(@path) + Page::Group::Show.perform do |group_show| + if group_show.has_subgroup?(path) + group_show.go_to_subgroup(path) else - page.go_to_new_subgroup + group_show.go_to_new_subgroup - Page::Group::New.perform do |group| - group.set_path(@path) - group.set_description(@description) - group.set_visibility('Public') - group.create + Page::Group::New.perform do |group_new| + group_new.set_path(path) + group_new.set_description(description) + group_new.set_visibility('Public') + group_new.create + end + + # Ensure that the group was actually created + group_show.wait(time: 1) do + group_show.has_text?(path) && + group_show.has_new_project_or_subgroup_dropdown? end end end diff --git a/qa/qa/page/shared/clone_panel.rb b/qa/qa/page/component/clone_panel.rb index 73e3dff956d..8e8ff4e3bb0 100644 --- a/qa/qa/page/shared/clone_panel.rb +++ b/qa/qa/page/component/clone_panel.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + module QA module Page - module Shared + module Component module ClonePanel def self.included(base) base.view 'app/views/shared/_clone_panel.html.haml' do diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb new file mode 100644 index 00000000000..69d465e8ac7 --- /dev/null +++ b/qa/qa/page/component/groups_filter.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module QA + module Page + module Component + module GroupsFilter + def self.included(base) + base.view 'app/views/shared/groups/_search_form.html.haml' do + element :groups_filter, 'search_field_tag :filter' + element :groups_filter_placeholder, 'Filter by name...' + end + + base.view 'app/views/shared/groups/_empty_state.html.haml' do + element :groups_empty_state + end + + base.view 'app/assets/javascripts/groups/components/groups.vue' do + element :groups_list_tree_container + end + end + + private + + def filter_by_name(name) + wait(reload: false) do + page.has_css?(element_selector_css(:groups_empty_state)) || + page.has_css?(element_selector_css(:groups_list_tree_container)) + end + + fill_in 'Filter by name...', with: name + end + end + end + end +end diff --git a/qa/qa/page/dashboard/groups.rb b/qa/qa/page/dashboard/groups.rb index e853e0d85e0..5654cc01e09 100644 --- a/qa/qa/page/dashboard/groups.rb +++ b/qa/qa/page/dashboard/groups.rb @@ -2,19 +2,12 @@ module QA module Page module Dashboard class Groups < Page::Base - view 'app/views/shared/groups/_search_form.html.haml' do - element :groups_filter, 'search_field_tag :filter' - element :groups_filter_placeholder, 'Filter by name...' - end + include Page::Component::GroupsFilter view 'app/views/dashboard/_groups_head.html.haml' do element :new_group_button, 'link_to _("New group")' end - def filter_by_name(name) - fill_in 'Filter by name...', with: name - end - def has_group?(name) filter_by_name(name) diff --git a/qa/qa/page/dashboard/projects.rb b/qa/qa/page/dashboard/projects.rb index 73942cb856a..5b2827c089c 100644 --- a/qa/qa/page/dashboard/projects.rb +++ b/qa/qa/page/dashboard/projects.rb @@ -3,6 +3,7 @@ module QA module Dashboard class Projects < Page::Base view 'app/views/dashboard/projects/index.html.haml' + view 'app/views/shared/projects/_search_form.html.haml' do element :form_filter_by_name, /form_tag.+id: 'project-filter-form'/ end @@ -13,6 +14,8 @@ module QA find_link(text: name).click end + private + def filter_by_name(name) page.within('form#project-filter-form') do fill_in :name, with: name diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb index 3e0eaa392f5..ac85f16d8af 100644 --- a/qa/qa/page/group/show.rb +++ b/qa/qa/page/group/show.rb @@ -2,6 +2,8 @@ module QA module Page module Group class Show < Page::Base + include Page::Component::GroupsFilter + view 'app/views/groups/show.html.haml' do element :new_project_or_subgroup_dropdown, '.new-project-subgroup' element :new_project_or_subgroup_dropdown_toggle, '.dropdown-toggle' @@ -21,8 +23,8 @@ module QA click_link name end - def filter_by_name(name) - fill_in 'Filter by name...', with: name + def has_new_project_or_subgroup_dropdown? + page.has_css?(element_selector_css(:new_project_or_subgroup_dropdown)) end def has_subgroup?(name) diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb index 5bc0598a524..587a02163b9 100644 --- a/qa/qa/page/project/issue/show.rb +++ b/qa/qa/page/project/issue/show.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module QA module Page module Project diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb index c751b472535..267e7bbc249 100644 --- a/qa/qa/page/project/show.rb +++ b/qa/qa/page/project/show.rb @@ -2,7 +2,7 @@ module QA module Page module Project class Show < Page::Base - include Page::Shared::ClonePanel + include Page::Component::ClonePanel view 'app/views/projects/_last_push.html.haml' do element :create_merge_request @@ -23,7 +23,7 @@ module QA end view 'app/views/projects/buttons/_fork.html.haml' do - element :fork_label, "%span= s_('GoToYourFork|Fork')" + element :fork_label, "%span= s_('ProjectOverview|Fork')" element :fork_link, "link_to new_project_fork_path(@project)" end @@ -32,7 +32,7 @@ module QA end view 'app/presenters/project_presenter.rb' do - element :new_file_button, "label: _('New file')," + element :new_file_button, "_('New file')," end def project_name diff --git a/qa/qa/page/project/wiki/show.rb b/qa/qa/page/project/wiki/show.rb index 044e514bab3..c47a715687f 100644 --- a/qa/qa/page/project/wiki/show.rb +++ b/qa/qa/page/project/wiki/show.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + module QA module Page module Project module Wiki class Show < Page::Base - include Page::Shared::ClonePanel + include Page::Component::ClonePanel view 'app/views/projects/wikis/pages.html.haml' do element :clone_repository_link, 'Clone repository' diff --git a/qa/qa/scenario/template.rb b/qa/qa/scenario/template.rb index a87d925ce32..cb1a1de6b9a 100644 --- a/qa/qa/scenario/template.rb +++ b/qa/qa/scenario/template.rb @@ -28,12 +28,8 @@ module QA Specs::Runner.perform do |specs| specs.tty = true - specs.options = - if rspec_options.any? - rspec_options - else - ['--tag', self.class.focus.join(','), '--', ::File.expand_path('../specs/features', __dir__)] - end + specs.tags = self.class.focus + specs.options = rspec_options if rspec_options.any? end end end diff --git a/qa/qa/scenario/test/instance.rb b/qa/qa/scenario/test/instance.rb index a2d503cc015..b4098619e4e 100644 --- a/qa/qa/scenario/test/instance.rb +++ b/qa/qa/scenario/test/instance.rb @@ -27,12 +27,7 @@ module QA Specs::Runner.perform do |specs| specs.tty = true - specs.options = - if rspec_options.any? - rspec_options - else - ['--', ::File.expand_path('../../specs/features', __dir__)] - end + specs.options = rspec_options if rspec_options.any? end end end diff --git a/qa/qa/scenario/test/integration/object_storage.rb b/qa/qa/scenario/test/integration/object_storage.rb index 874789db20d..2e028bbb5c6 100644 --- a/qa/qa/scenario/test/integration/object_storage.rb +++ b/qa/qa/scenario/test/integration/object_storage.rb @@ -4,7 +4,7 @@ module QA module Scenario module Test module Integration - class ObjectStorage < Test::Instance + class ObjectStorage < Test::Instance::All tags :object_storage end end diff --git a/qa/qa/scenario/test/sanity/failing.rb b/qa/qa/scenario/test/sanity/failing.rb new file mode 100644 index 00000000000..03452f6693d --- /dev/null +++ b/qa/qa/scenario/test/sanity/failing.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module QA + module Scenario + module Test + module Sanity + ## + # This scenario exits with a 1 exit code. + # + class Failing < Template + include Bootable + + tags :failing + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb index dd24e8ffba5..e558049756d 100644 --- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -30,7 +30,7 @@ module QA push.project = project push.directory = Pathname .new(__dir__) - .join('../../../fixtures/auto_devops_rack') + .join('../../../../../fixtures/auto_devops_rack') push.commit_message = 'Create Auto DevOps compatible rack application' end diff --git a/qa/qa/specs/features/sanity/failing_spec.rb b/qa/qa/specs/features/sanity/failing_spec.rb new file mode 100644 index 00000000000..7e0480e9067 --- /dev/null +++ b/qa/qa/specs/features/sanity/failing_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module QA + context 'Sanity checks', :orchestrated, :failing do + describe 'Failing orchestrated example' do + it 'always fails' do + Runtime::Browser.visit(:gitlab, Page::Main::Login) + + expect(page).to have_text("These Aren't the Texts You're Looking For", wait: 1) + end + end + end +end diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb index ccb9d5591de..5b5699d8a93 100644 --- a/qa/qa/specs/runner.rb +++ b/qa/qa/specs/runner.rb @@ -16,9 +16,9 @@ module QA args.push('--tty') if tty if tags.any? - tags.each { |tag| args.push(['-t', tag.to_s]) } + tags.each { |tag| args.push(['--tag', tag.to_s]) } else - args.push(%w[-t ~orchestrated]) + args.push(%w[--tag ~orchestrated]) end args.push(options) diff --git a/qa/spec/git/repository_spec.rb b/qa/spec/git/repository_spec.rb index 5c65128d10c..53bff3bf0b3 100644 --- a/qa/spec/git/repository_spec.rb +++ b/qa/spec/git/repository_spec.rb @@ -29,7 +29,7 @@ describe QA::Git::Repository do def cd_empty_temp_directory tmp_dir = 'tmp/git-repository-spec/' - FileUtils.rm_r(tmp_dir) if ::File.exist?(tmp_dir) + FileUtils.rm_rf(tmp_dir) if ::File.exist?(tmp_dir) FileUtils.mkdir_p tmp_dir FileUtils.cd tmp_dir end diff --git a/qa/spec/scenario/test/instance/all_spec.rb b/qa/spec/scenario/test/instance/all_spec.rb index 1d96352550b..9311d1d8199 100644 --- a/qa/spec/scenario/test/instance/all_spec.rb +++ b/qa/spec/scenario/test/instance/all_spec.rb @@ -1,45 +1,3 @@ describe QA::Scenario::Test::Instance::All do - subject do - Class.new(described_class) do - tags :rspec, :foo - end - end - - context '#perform' do - let(:arguments) { spy('Runtime::Scenario') } - let(:release) { spy('Runtime::Release') } - let(:runner) { spy('Specs::Runner') } - - before do - stub_const('QA::Runtime::Release', release) - stub_const('QA::Runtime::Scenario', arguments) - stub_const('QA::Specs::Runner', runner) - - allow(runner).to receive(:perform).and_yield(runner) - end - - it 'sets an address of the subject' do - subject.perform("hello") - - expect(arguments).to have_received(:define) - .with(:gitlab_address, "hello") - end - - context 'no paths' do - it 'calls runner with default arguments' do - subject.perform("test") - - expect(runner).to have_received(:options=) - .with(['--tag', 'rspec,foo', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)]) - end - end - - context 'specifying paths' do - it 'calls runner with paths' do - subject.perform('test', 'path1', 'path2') - - expect(runner).to have_received(:options=).with(%w[path1 path2]) - end - end - end + it_behaves_like 'a QA scenario class' end diff --git a/qa/spec/scenario/test/instance/smoke_spec.rb b/qa/spec/scenario/test/instance/smoke_spec.rb index 386eefae930..b5db9783af3 100644 --- a/qa/spec/scenario/test/instance/smoke_spec.rb +++ b/qa/spec/scenario/test/instance/smoke_spec.rb @@ -1,45 +1,5 @@ describe QA::Scenario::Test::Instance::Smoke do - subject { Class.new(described_class) { tags :smoke } } - - context '#perform' do - let(:arguments) { spy('Runtime::Scenario') } - let(:release) { spy('Runtime::Release') } - let(:runner) { spy('Specs::Runner') } - - before do - stub_const('QA::Runtime::Release', release) - stub_const('QA::Runtime::Scenario', arguments) - stub_const('QA::Specs::Runner', runner) - - allow(runner).to receive(:perform).and_yield(runner) - end - - it 'sets an address of the subject' do - subject.perform("hello") - - expect(arguments).to have_received(:define) - .with(:gitlab_address, "hello") - end - - it 'has a smoke tag' do - expect(subject.focus).to eq([:smoke]) # rubocop:disable Focus - end - - context 'no paths' do - it 'calls runner with default arguments' do - subject.perform("test") - - expect(runner).to have_received(:options=) - .with(['--tag', 'smoke', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)]) - end - end - - context 'specifying paths' do - it 'calls runner with paths' do - subject.perform('test', 'path1', 'path2') - - expect(runner).to have_received(:options=).with(%w[path1 path2]) - end - end + it_behaves_like 'a QA scenario class' do + let(:tags) { [:smoke] } end end diff --git a/qa/spec/scenario/test/integration/github_spec.rb b/qa/spec/scenario/test/integration/github_spec.rb new file mode 100644 index 00000000000..c2aeb1ded1d --- /dev/null +++ b/qa/spec/scenario/test/integration/github_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +describe QA::Scenario::Test::Integration::Github do + context '#perform' do + let(:env) { spy('Runtime::Env') } + + before do + stub_const('QA::Runtime::Env', env) + end + + it_behaves_like 'a QA scenario class' do + let(:tags) { [:github] } + + it 'requires a GitHub access token' do + subject.perform('gitlab_address') + + expect(env).to have_received(:require_github_access_token!) + end + end + end +end diff --git a/qa/spec/scenario/test/integration/kubernetes_spec.rb b/qa/spec/scenario/test/integration/kubernetes_spec.rb new file mode 100644 index 00000000000..cb43994b229 --- /dev/null +++ b/qa/spec/scenario/test/integration/kubernetes_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +describe QA::Scenario::Test::Integration::Kubernetes do + context '#perform' do + it_behaves_like 'a QA scenario class' do + let(:tags) { [:kubernetes] } + end + end +end diff --git a/qa/spec/scenario/test/integration/ldap_spec.rb b/qa/spec/scenario/test/integration/ldap_spec.rb new file mode 100644 index 00000000000..198856aec3f --- /dev/null +++ b/qa/spec/scenario/test/integration/ldap_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +describe QA::Scenario::Test::Integration::LDAP do + context '#perform' do + it_behaves_like 'a QA scenario class' do + let(:tags) { [:ldap] } + end + end +end diff --git a/qa/spec/scenario/test/integration/mattermost_spec.rb b/qa/spec/scenario/test/integration/mattermost_spec.rb new file mode 100644 index 00000000000..59caf2ba2cd --- /dev/null +++ b/qa/spec/scenario/test/integration/mattermost_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +describe QA::Scenario::Test::Integration::Mattermost do + context '#perform' do + it_behaves_like 'a QA scenario class' do + let(:args) { %w[gitlab_address mattermost_address] } + let(:tags) { [:mattermost] } + let(:options) { ['path1']} + + it 'requires a GitHub access token' do + subject.perform(*args) + + expect(attributes).to have_received(:define) + .with(:mattermost_address, 'mattermost_address') + end + end + end +end diff --git a/qa/spec/scenario/test/integration/object_storage_spec.rb b/qa/spec/scenario/test/integration/object_storage_spec.rb new file mode 100644 index 00000000000..2b7188223e0 --- /dev/null +++ b/qa/spec/scenario/test/integration/object_storage_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +describe QA::Scenario::Test::Integration::ObjectStorage do + context '#perform' do + it_behaves_like 'a QA scenario class' do + let(:tags) { [:object_storage] } + end + end +end diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb new file mode 100644 index 00000000000..b237b954889 --- /dev/null +++ b/qa/spec/specs/runner_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +describe QA::Specs::Runner do + context '#perform' do + before do + allow(QA::Runtime::Browser).to receive(:configure!) + end + + it 'excludes the orchestrated tag by default' do + expect(RSpec::Core::Runner).to receive(:run) + .with(['--tag', '~orchestrated', File.expand_path('../../qa/specs/features', __dir__)], $stderr, $stdout) + .and_return(0) + + subject.perform + end + + context 'when tty is set' do + subject do + described_class.new.tap do |runner| + runner.tty = true + end + end + + it 'sets the `--tty` flag' do + expect(RSpec::Core::Runner).to receive(:run) + .with(['--tty', '--tag', '~orchestrated', File.expand_path('../../qa/specs/features', __dir__)], $stderr, $stdout) + .and_return(0) + + subject.perform + end + end + + context 'when tags are set' do + subject do + described_class.new.tap do |runner| + runner.tags = %i[orchestrated github] + end + end + + it 'focuses on the given tags' do + expect(RSpec::Core::Runner).to receive(:run) + .with(['--tag', 'orchestrated', '--tag', 'github', File.expand_path('../../qa/specs/features', __dir__)], $stderr, $stdout) + .and_return(0) + + subject.perform + end + end + end +end diff --git a/qa/spec/support/shared_examples/scenario_shared_examples.rb b/qa/spec/support/shared_examples/scenario_shared_examples.rb new file mode 100644 index 00000000000..5fd55d7d96b --- /dev/null +++ b/qa/spec/support/shared_examples/scenario_shared_examples.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +shared_examples 'a QA scenario class' do + let(:attributes) { spy('Runtime::Scenario') } + let(:release) { spy('Runtime::Release') } + let(:runner) { spy('Specs::Runner') } + + let(:args) { ['gitlab_address'] } + let(:tags) { [] } + let(:options) { %w[path1 path2] } + + before do + stub_const('QA::Runtime::Release', release) + stub_const('QA::Runtime::Scenario', attributes) + stub_const('QA::Specs::Runner', runner) + + allow(runner).to receive(:perform).and_yield(runner) + end + + it 'responds to perform' do + expect(subject).to respond_to(:perform) + end + + it 'sets an address of the subject' do + subject.perform(*args) + + expect(attributes).to have_received(:define).with(:gitlab_address, 'gitlab_address') + end + + it 'performs before hooks' do + subject.perform(*args) + + expect(release).to have_received(:perform_before_hooks) + end + + it 'sets tags on runner' do + subject.perform(*args) + + expect(runner).to have_received(:tags=).with(tags) + end + + context 'specifying RSpec options' do + it 'sets options on runner' do + subject.perform(*args, *options) + + expect(runner).to have_received(:options=).with(options) + end + end +end |