summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rw-r--r--qa/.gitignore1
-rwxr-xr-xqa/bin/qa2
-rw-r--r--qa/qa.rb2
-rw-r--r--qa/qa/git/repository.rb2
-rw-r--r--qa/qa/page/base.rb2
-rw-r--r--qa/qa/page/main/entry.rb21
-rw-r--r--qa/qa/page/main/login.rb19
-rw-r--r--qa/qa/page/mattermost/login.rb2
-rw-r--r--qa/qa/page/mattermost/main.rb2
-rw-r--r--qa/qa/runtime/scenario.rb22
-rw-r--r--qa/qa/scenario/bootable.rb45
-rw-r--r--qa/qa/scenario/entrypoint.rb28
-rw-r--r--qa/qa/scenario/test/integration/mattermost.rb3
-rw-r--r--qa/qa/specs/config.rb9
-rw-r--r--qa/qa/specs/features/login/standard_spec.rb3
-rw-r--r--qa/qa/specs/features/mattermost/group_create_spec.rb3
-rw-r--r--qa/qa/specs/features/mattermost/login_spec.rb3
-rw-r--r--qa/qa/specs/features/project/create_spec.rb3
-rw-r--r--qa/qa/specs/features/repository/clone_spec.rb3
-rw-r--r--qa/qa/specs/features/repository/push_spec.rb3
-rw-r--r--qa/qa/specs/runner.rb22
-rw-r--r--qa/spec/runtime/scenario_spec.rb27
-rw-r--r--qa/spec/scenario/bootable_spec.rb24
-rw-r--r--qa/spec/scenario/entrypoint_spec.rb20
24 files changed, 201 insertions, 70 deletions
diff --git a/qa/.gitignore b/qa/.gitignore
index 3fec32c8427..19ec17d0005 100644
--- a/qa/.gitignore
+++ b/qa/.gitignore
@@ -1 +1,2 @@
tmp/
+.ruby-version
diff --git a/qa/bin/qa b/qa/bin/qa
index cecdeac14db..6a772e93cee 100755
--- a/qa/bin/qa
+++ b/qa/bin/qa
@@ -4,4 +4,4 @@ require_relative '../qa'
QA::Scenario
.const_get(ARGV.shift)
- .perform(*ARGV)
+ .launch!(ARGV)
diff --git a/qa/qa.rb b/qa/qa.rb
index e8689a44f4d..dc1cd9abc6a 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -18,6 +18,7 @@ module QA
##
# Support files
#
+ autoload :Bootable, 'qa/scenario/bootable'
autoload :Actable, 'qa/scenario/actable'
autoload :Entrypoint, 'qa/scenario/entrypoint'
autoload :Template, 'qa/scenario/template'
@@ -61,6 +62,7 @@ module QA
module Main
autoload :Entry, 'qa/page/main/entry'
+ autoload :Login, 'qa/page/main/login'
autoload :Menu, 'qa/page/main/menu'
end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index b9e199000d6..59cd147e055 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -23,7 +23,7 @@ module QA
def password=(pass)
@password = pass
- @uri.password = pass
+ @uri.password = CGI.escape(pass)
end
def use_default_credentials
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index d55326c5262..bdddfb877c5 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -5,7 +5,7 @@ module QA
include Scenario::Actable
def refresh
- visit current_path
+ visit current_url
end
end
end
diff --git a/qa/qa/page/main/entry.rb b/qa/qa/page/main/entry.rb
index a9810beeb29..ac939732b1d 100644
--- a/qa/qa/page/main/entry.rb
+++ b/qa/qa/page/main/entry.rb
@@ -2,9 +2,14 @@ module QA
module Page
module Main
class Entry < Page::Base
- def initialize
- visit('/')
+ def visit_login_page
+ visit("#{Runtime::Scenario.gitlab_address}/users/sign_in")
+ wait_for_instance_to_be_ready
+ end
+
+ private
+ def wait_for_instance_to_be_ready
# This resolves cold boot / background tasks problems
#
start = Time.now
@@ -14,18 +19,6 @@ module QA
refresh
end
end
-
- def sign_in_using_credentials
- if page.has_content?('Change your password')
- fill_in :user_password, with: Runtime::User.password
- fill_in :user_password_confirmation, with: Runtime::User.password
- click_button 'Change your password'
- end
-
- fill_in :user_login, with: Runtime::User.name
- fill_in :user_password, with: Runtime::User.password
- click_button 'Sign in'
- end
end
end
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
new file mode 100644
index 00000000000..8b0111a78a2
--- /dev/null
+++ b/qa/qa/page/main/login.rb
@@ -0,0 +1,19 @@
+module QA
+ module Page
+ module Main
+ class Login < Page::Base
+ def sign_in_using_credentials
+ if page.has_content?('Change your password')
+ fill_in :user_password, with: Runtime::User.password
+ fill_in :user_password_confirmation, with: Runtime::User.password
+ click_button 'Change your password'
+ end
+
+ fill_in :user_login, with: Runtime::User.name
+ fill_in :user_password, with: Runtime::User.password
+ click_button 'Sign in'
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/mattermost/login.rb b/qa/qa/page/mattermost/login.rb
index 2001dc5b230..42ab9c6f675 100644
--- a/qa/qa/page/mattermost/login.rb
+++ b/qa/qa/page/mattermost/login.rb
@@ -3,7 +3,7 @@ module QA
module Mattermost
class Login < Page::Base
def initialize
- visit(Runtime::Scenario.mattermost + '/login')
+ visit(Runtime::Scenario.mattermost_address + '/login')
end
def sign_in_using_oauth
diff --git a/qa/qa/page/mattermost/main.rb b/qa/qa/page/mattermost/main.rb
index e636d7676f4..4b8fc28e53f 100644
--- a/qa/qa/page/mattermost/main.rb
+++ b/qa/qa/page/mattermost/main.rb
@@ -3,7 +3,7 @@ module QA
module Mattermost
class Main < Page::Base
def initialize
- visit(Runtime::Scenario.mattermost)
+ visit(Runtime::Scenario.mattermost_address)
end
end
end
diff --git a/qa/qa/runtime/scenario.rb b/qa/qa/runtime/scenario.rb
index 0c5e9787e17..7ef59046640 100644
--- a/qa/qa/runtime/scenario.rb
+++ b/qa/qa/runtime/scenario.rb
@@ -1,8 +1,28 @@
module QA
module Runtime
+ ##
+ # Singleton approach to global test scenario arguments.
+ #
module Scenario
extend self
- attr_accessor :mattermost
+
+ attr_reader :attributes
+
+ def define(attribute, value)
+ (@attributes ||= {}).store(attribute.to_sym, value)
+
+ define_singleton_method(attribute) do
+ @attributes[attribute.to_sym].tap do |value|
+ if value.to_s.empty?
+ raise ArgumentError, "Empty `#{attribute}` attribute!"
+ end
+ end
+ end
+ end
+
+ def method_missing(name, *)
+ raise ArgumentError, "Scenario attribute `#{name}` not defined!"
+ end
end
end
end
diff --git a/qa/qa/scenario/bootable.rb b/qa/qa/scenario/bootable.rb
new file mode 100644
index 00000000000..cf8996cd597
--- /dev/null
+++ b/qa/qa/scenario/bootable.rb
@@ -0,0 +1,45 @@
+require 'optparse'
+
+module QA
+ module Scenario
+ module Bootable
+ Option = Struct.new(:name, :arg, :desc)
+
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def launch!(argv)
+ return self.perform(*argv) unless has_attributes?
+
+ arguments = OptionParser.new do |parser|
+ options.to_a.each do |opt|
+ parser.on(opt.arg, opt.desc) do |value|
+ Runtime::Scenario.define(opt.name, value)
+ end
+ end
+ end
+
+ arguments.parse!(argv)
+
+ self.perform(**Runtime::Scenario.attributes)
+ end
+
+ private
+
+ def attribute(name, arg, desc)
+ options.push(Option.new(name, arg, desc))
+ end
+
+ def options
+ @options ||= []
+ end
+
+ def has_attributes?
+ options.any?
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/scenario/entrypoint.rb b/qa/qa/scenario/entrypoint.rb
index 33cb2696f8f..ae099fd911e 100644
--- a/qa/qa/scenario/entrypoint.rb
+++ b/qa/qa/scenario/entrypoint.rb
@@ -5,18 +5,10 @@ module QA
# including staging and on-premises installation.
#
class Entrypoint < Template
- def self.tags(*tags)
- @tags = tags
- end
-
- def self.get_tags
- @tags
- end
+ include Bootable
def perform(address, *files)
- Specs::Config.perform do |specs|
- specs.address = address
- end
+ Runtime::Scenario.define(:gitlab_address, address)
##
# Perform before hooks, which are different for CE and EE
@@ -24,13 +16,19 @@ module QA
Runtime::Release.perform_before_hooks
Specs::Runner.perform do |specs|
- specs.rspec(
- tty: true,
- tags: self.class.get_tags,
- files: files.any? ? files : 'qa/specs/features'
- )
+ specs.tty = true
+ specs.tags = self.class.get_tags
+ specs.files = files.any? ? files : 'qa/specs/features'
end
end
+
+ def self.tags(*tags)
+ @tags = tags
+ end
+
+ def self.get_tags
+ @tags
+ end
end
end
end
diff --git a/qa/qa/scenario/test/integration/mattermost.rb b/qa/qa/scenario/test/integration/mattermost.rb
index 0220da929ce..7d0702afdb1 100644
--- a/qa/qa/scenario/test/integration/mattermost.rb
+++ b/qa/qa/scenario/test/integration/mattermost.rb
@@ -10,7 +10,8 @@ module QA
tags :core, :mattermost
def perform(address, mattermost, *files)
- Runtime::Scenario.mattermost = mattermost
+ Runtime::Scenario.define(:mattermost_address, mattermost)
+
super(address, *files)
end
end
diff --git a/qa/qa/specs/config.rb b/qa/qa/specs/config.rb
index 79c681168cc..591ddde8ab9 100644
--- a/qa/qa/specs/config.rb
+++ b/qa/qa/specs/config.rb
@@ -9,15 +9,7 @@ require 'selenium-webdriver'
module QA
module Specs
class Config < Scenario::Template
- attr_writer :address
-
- def initialize
- @address = ENV['GITLAB_URL']
- end
-
def perform
- raise 'Please configure GitLab address!' unless @address
-
configure_rspec!
configure_capybara!
end
@@ -56,7 +48,6 @@ module QA
end
Capybara.configure do |config|
- config.app_host = @address
config.default_driver = :chrome
config.javascript_driver = :chrome
config.default_max_wait_time = 4
diff --git a/qa/qa/specs/features/login/standard_spec.rb b/qa/qa/specs/features/login/standard_spec.rb
index ba19ce17ee5..b155708c387 100644
--- a/qa/qa/specs/features/login/standard_spec.rb
+++ b/qa/qa/specs/features/login/standard_spec.rb
@@ -1,7 +1,8 @@
module QA
feature 'standard root login', :core do
scenario 'user logs in using credentials' do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
# TODO, since `Signed in successfully` message was removed
# this is the only way to tell if user is signed in correctly.
diff --git a/qa/qa/specs/features/mattermost/group_create_spec.rb b/qa/qa/specs/features/mattermost/group_create_spec.rb
index c4afd83c8e4..853a9a6a4f4 100644
--- a/qa/qa/specs/features/mattermost/group_create_spec.rb
+++ b/qa/qa/specs/features/mattermost/group_create_spec.rb
@@ -1,7 +1,8 @@
module QA
feature 'create a new group', :mattermost do
scenario 'creating a group with a mattermost team' do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
Page::Main::Menu.act { go_to_groups }
Page::Dashboard::Groups.perform do |page|
diff --git a/qa/qa/specs/features/mattermost/login_spec.rb b/qa/qa/specs/features/mattermost/login_spec.rb
index a89a6a3d1cf..92f91cb2725 100644
--- a/qa/qa/specs/features/mattermost/login_spec.rb
+++ b/qa/qa/specs/features/mattermost/login_spec.rb
@@ -1,7 +1,8 @@
module QA
feature 'logging in to Mattermost', :mattermost do
scenario 'can use gitlab oauth' do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
Page::Mattermost::Login.act { sign_in_using_oauth }
Page::Mattermost::Main.perform do |page|
diff --git a/qa/qa/specs/features/project/create_spec.rb b/qa/qa/specs/features/project/create_spec.rb
index 27eb22f15a6..aba0c2b4c14 100644
--- a/qa/qa/specs/features/project/create_spec.rb
+++ b/qa/qa/specs/features/project/create_spec.rb
@@ -1,7 +1,8 @@
module QA
feature 'create a new project', :core do
scenario 'user creates a new project' do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |project|
project.name = 'awesome-project'
diff --git a/qa/qa/specs/features/repository/clone_spec.rb b/qa/qa/specs/features/repository/clone_spec.rb
index 3571173783d..5cc3b3b9c1b 100644
--- a/qa/qa/specs/features/repository/clone_spec.rb
+++ b/qa/qa/specs/features/repository/clone_spec.rb
@@ -9,7 +9,8 @@ module QA
end
before do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |scenario|
scenario.name = 'project-with-code'
diff --git a/qa/qa/specs/features/repository/push_spec.rb b/qa/qa/specs/features/repository/push_spec.rb
index 0e691fb0d75..30935dc1e13 100644
--- a/qa/qa/specs/features/repository/push_spec.rb
+++ b/qa/qa/specs/features/repository/push_spec.rb
@@ -2,7 +2,8 @@ module QA
feature 'push code to repository', :core do
context 'with regular account over http' do
scenario 'user pushes code to the repository' do
- Page::Main::Entry.act { sign_in_using_credentials }
+ Page::Main::Entry.act { visit_login_page }
+ Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |scenario|
scenario.name = 'project_with_code'
diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb
index 2aa18d5d3a1..f98b8f88e9a 100644
--- a/qa/qa/specs/runner.rb
+++ b/qa/qa/specs/runner.rb
@@ -2,16 +2,22 @@ require 'rspec/core'
module QA
module Specs
- class Runner
- include Scenario::Actable
+ class Runner < Scenario::Template
+ attr_accessor :tty, :tags, :files
- def rspec(tty: false, tags: [], files: ['qa/specs/features'])
+ def initialize
+ @tty = false
+ @tags = []
+ @files = ['qa/specs/features']
+ end
+
+ def perform
args = []
- args << '--tty' if tty
- tags.to_a.each do |tag|
- args << ['-t', tag.to_s]
- end
- args << files
+ args.push('--tty') if tty
+ tags.to_a.each { |tag| args.push(['-t', tag.to_s]) }
+ args.push(files)
+
+ Specs::Config.perform
RSpec::Core::Runner.run(args.flatten, $stderr, $stdout).tap do |status|
abort if status.nonzero?
diff --git a/qa/spec/runtime/scenario_spec.rb b/qa/spec/runtime/scenario_spec.rb
new file mode 100644
index 00000000000..7009192bcc0
--- /dev/null
+++ b/qa/spec/runtime/scenario_spec.rb
@@ -0,0 +1,27 @@
+describe QA::Runtime::Scenario do
+ subject do
+ Module.new.extend(described_class)
+ end
+
+ it 'makes it possible to define global scenario attributes' do
+ subject.define(:my_attribute, 'some-value')
+ subject.define(:another_attribute, 'another-value')
+
+ expect(subject.my_attribute).to eq 'some-value'
+ expect(subject.another_attribute).to eq 'another-value'
+ expect(subject.attributes)
+ .to eq(my_attribute: 'some-value', another_attribute: 'another-value')
+ end
+
+ it 'raises error when attribute is not known' do
+ expect { subject.invalid_accessor }
+ .to raise_error ArgumentError, /invalid_accessor/
+ end
+
+ it 'raises error when attribute is empty' do
+ subject.define(:empty_attribute, '')
+
+ expect { subject.empty_attribute }
+ .to raise_error ArgumentError, /empty_attribute/
+ end
+end
diff --git a/qa/spec/scenario/bootable_spec.rb b/qa/spec/scenario/bootable_spec.rb
new file mode 100644
index 00000000000..273aac7677e
--- /dev/null
+++ b/qa/spec/scenario/bootable_spec.rb
@@ -0,0 +1,24 @@
+describe QA::Scenario::Bootable do
+ subject do
+ Class.new(QA::Scenario::Template)
+ .include(described_class)
+ end
+
+ it 'makes it possible to define the scenario attribute' do
+ subject.class_eval do
+ attribute :something, '--something SOMETHING', 'Some attribute'
+ attribute :another, '--another ANOTHER', 'Some other attribute'
+ end
+
+ expect(subject).to receive(:perform)
+ .with(something: 'test', another: 'other')
+
+ subject.launch!(%w[--another other --something test])
+ end
+
+ it 'does not require attributes to be defined' do
+ expect(subject).to receive(:perform).with('some', 'argv')
+
+ subject.launch!(%w[some argv])
+ end
+end
diff --git a/qa/spec/scenario/entrypoint_spec.rb b/qa/spec/scenario/entrypoint_spec.rb
index 3fd068b641c..aec79dcea04 100644
--- a/qa/spec/scenario/entrypoint_spec.rb
+++ b/qa/spec/scenario/entrypoint_spec.rb
@@ -6,31 +6,30 @@ describe QA::Scenario::Entrypoint do
end
context '#perform' do
- let(:config) { spy('Specs::Config') }
+ let(:arguments) { spy('Runtime::Scenario') }
let(:release) { spy('Runtime::Release') }
let(:runner) { spy('Specs::Runner') }
before do
- allow(config).to receive(:perform) { |&block| block.call config }
- allow(runner).to receive(:perform) { |&block| block.call runner }
-
- stub_const('QA::Specs::Config', config)
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 'should set address' do
+ it 'sets an address of the subject' do
subject.perform("hello")
- expect(config).to have_received(:address=).with("hello")
+ expect(arguments).to have_received(:define)
+ .with(:gitlab_address, "hello")
end
context 'no paths' do
it 'should call runner with default arguments' do
subject.perform("test")
- expect(runner).to have_received(:rspec)
- .with(hash_including(files: 'qa/specs/features'))
+ expect(runner).to have_received(:files=).with('qa/specs/features')
end
end
@@ -38,8 +37,7 @@ describe QA::Scenario::Entrypoint do
it 'should call runner with paths' do
subject.perform('test', 'path1', 'path2')
- expect(runner).to have_received(:rspec)
- .with(hash_including(files: %w(path1 path2)))
+ expect(runner).to have_received(:files=).with(%w[path1 path2])
end
end
end