Commit 1a1f28fe authored by Ramya Authappan's avatar Ramya Authappan

Merge branch 'qa-improve-wait-for-push' into 'master'

[CE] Improve `wait_for_push`

Closes #53308

See merge request gitlab-org/gitlab-ce!24085
parents 25af9032 97265d39
...@@ -62,6 +62,11 @@ module QA ...@@ -62,6 +62,11 @@ module QA
autoload :Fork, 'qa/resource/fork' autoload :Fork, 'qa/resource/fork'
autoload :SSHKey, 'qa/resource/ssh_key' autoload :SSHKey, 'qa/resource/ssh_key'
module Events
autoload :Base, 'qa/resource/events/base'
autoload :Project, 'qa/resource/events/project'
end
module Repository module Repository
autoload :Push, 'qa/resource/repository/push' autoload :Push, 'qa/resource/repository/push'
autoload :ProjectPush, 'qa/resource/repository/project_push' autoload :ProjectPush, 'qa/resource/repository/project_push'
...@@ -361,6 +366,7 @@ module QA ...@@ -361,6 +366,7 @@ module QA
autoload :Logging, 'qa/support/page/logging' autoload :Logging, 'qa/support/page/logging'
end end
autoload :Api, 'qa/support/api' autoload :Api, 'qa/support/api'
autoload :Waiter, 'qa/support/waiter'
end end
end end
......
...@@ -18,19 +18,10 @@ module QA ...@@ -18,19 +18,10 @@ module QA
page.refresh page.refresh
end end
def wait(max: 60, time: 0.1, reload: true) def wait(max: 60, interval: 0.1, reload: true)
start = Time.now QA::Support::Waiter.wait(max: max, interval: interval) do
yield || (reload && refresh && false)
while Time.now - start < max
result = yield
return result if result
sleep(time)
refresh if reload
end end
false
end end
def with_retry(max_attempts: 3, reload: false) def with_retry(max_attempts: 3, reload: false)
...@@ -73,7 +64,7 @@ module QA ...@@ -73,7 +64,7 @@ module QA
xhr.send(); xhr.send();
JS JS
return false unless wait(time: 0.5, max: 60, reload: false) do return false unless wait(interval: 0.5, max: 60, reload: false) do
page.evaluate_script('xhr.readyState == XMLHttpRequest.DONE') page.evaluate_script('xhr.readyState == XMLHttpRequest.DONE')
end end
......
...@@ -21,11 +21,6 @@ module QA ...@@ -21,11 +21,6 @@ module QA
repository_clone_location(:ssh_clone_url) repository_clone_location(:ssh_clone_url)
end end
def wait_for_push
sleep 5
refresh
end
private private
def repository_clone_location(kind) def repository_clone_location(kind)
......
...@@ -27,11 +27,6 @@ module QA ...@@ -27,11 +27,6 @@ module QA
Git::Location.new(find('#project_clone').value) Git::Location.new(find('#project_clone').value)
end end
def wait_for_push
sleep 5
refresh
end
private private
def choose_repository_clone(kind, detect_text) def choose_repository_clone(kind, detect_text)
......
...@@ -148,7 +148,7 @@ module QA ...@@ -148,7 +148,7 @@ module QA
end end
def add_comment_to_diff(text) def add_comment_to_diff(text)
wait(time: 5) do wait(interval: 5) do
has_text?("No newline at end of file") has_text?("No newline at end of file")
end end
all_elements(:new_diff_line).first.hover all_elements(:new_diff_line).first.hover
......
...@@ -62,7 +62,7 @@ module QA ...@@ -62,7 +62,7 @@ module QA
sleep 5 sleep 5
refresh refresh
wait(time: 1) do wait(interval: 1) do
within_element_by_index(:mirrored_repository_row, row_index) do within_element_by_index(:mirrored_repository_row, row_index) do
last_update = find_element(:mirror_last_update_at, wait: 0) last_update = find_element(:mirror_last_update_at, wait: 0)
last_update.has_text?('just now') || last_update.has_text?('seconds') last_update.has_text?('just now') || last_update.has_text?('seconds')
......
...@@ -27,6 +27,10 @@ module QA ...@@ -27,6 +27,10 @@ module QA
attributes.each(&method(:public_send)) attributes.each(&method(:public_send))
end end
def wait(max: 60, interval: 0.1)
QA::Support::Waiter.wait(max: max, interval: interval)
end
private private
def populate_attribute(name, block) def populate_attribute(name, block)
......
# frozen_string_literal: true
module QA
module Resource
module Events
MAX_WAIT = 10
EventNotFoundError = Class.new(RuntimeError)
module Base
def events(action: nil)
path = [api_get_events]
path << "?action=#{CGI.escape(action)}" if action
parse_body(api_get_from("#{path.join}"))
end
private
def api_get_events
"#{api_get_path}/events"
end
def wait_for_event
event_found = QA::Support::Waiter.wait(max: max_wait) do
yield
end
raise EventNotFoundError, "Timed out waiting for event" unless event_found
end
def max_wait
MAX_WAIT
end
end
end
end
end
# frozen_string_literal: true
module QA
module Resource
module Events
module Project
include Events::Base
def wait_for_push(commit_message)
QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"])
wait_for_event do
events(action: 'pushed').any? { |event| event.dig(:push_data, :commit_title) == commit_message }
end
end
def wait_for_push_new_branch(branch_name = "master")
QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"])
wait_for_event do
events(action: 'pushed').any? { |event| event.dig(:push_data, :ref) == branch_name }
end
end
end
end
end
end
...@@ -5,12 +5,12 @@ module QA ...@@ -5,12 +5,12 @@ module QA
class Fork < Base class Fork < Base
attribute :project do attribute :project do
Resource::Project.fabricate! do |resource| Resource::Project.fabricate! do |resource|
resource.name = push.project.name resource.name = upstream.project.name
resource.path_with_namespace = "#{user.name}/#{push.project.name}" resource.path_with_namespace = "#{user.name}/#{upstream.project.name}"
end end
end end
attribute :push do attribute :upstream do
Repository::ProjectPush.fabricate! Repository::ProjectPush.fabricate!
end end
...@@ -24,7 +24,7 @@ module QA ...@@ -24,7 +24,7 @@ module QA
end end
def fabricate! def fabricate!
populate(:push, :user) populate(:upstream, :user)
# Sign out as admin and sign is as the fork user # Sign out as admin and sign is as the fork user
Page::Main::Menu.perform(&:sign_out) Page::Main::Menu.perform(&:sign_out)
...@@ -33,7 +33,7 @@ module QA ...@@ -33,7 +33,7 @@ module QA
login.sign_in_using_credentials(user) login.sign_in_using_credentials(user)
end end
push.project.visit! upstream.project.visit!
Page::Project::Show.perform(&:fork_project) Page::Project::Show.perform(&:fork_project)
......
...@@ -33,7 +33,7 @@ module QA ...@@ -33,7 +33,7 @@ module QA
end end
# Ensure that the group was actually created # Ensure that the group was actually created
group_show.wait(time: 1) do group_show.wait(interval: 1) do
group_show.has_text?(path) && group_show.has_text?(path) &&
group_show.has_new_project_or_subgroup_dropdown? group_show.has_new_project_or_subgroup_dropdown?
end end
......
...@@ -58,10 +58,7 @@ module QA ...@@ -58,10 +58,7 @@ module QA
populate(:target, :source) populate(:target, :source)
project.visit! project.visit!
Page::Project::Show.perform do |project| Page::Project::Show.perform(&:new_merge_request)
project.wait_for_push
project.new_merge_request
end
Page::MergeRequest::New.perform do |page| Page::MergeRequest::New.perform do |page|
page.fill_title(@title) page.fill_title(@title)
page.fill_description(@description) page.fill_description(@description)
......
...@@ -5,6 +5,8 @@ require 'securerandom' ...@@ -5,6 +5,8 @@ require 'securerandom'
module QA module QA
module Resource module Resource
class Project < Base class Project < Base
include Events::Project
attribute :name attribute :name
attribute :description attribute :description
......
...@@ -4,6 +4,8 @@ module QA ...@@ -4,6 +4,8 @@ module QA
module Resource module Resource
module Repository module Repository
class ProjectPush < Repository::Push class ProjectPush < Repository::Push
attr_writer :wait_for_push
attribute :project do attribute :project do
Project.fabricate! do |resource| Project.fabricate! do |resource|
resource.name = 'project-with-code' resource.name = 'project-with-code'
...@@ -17,6 +19,7 @@ module QA ...@@ -17,6 +19,7 @@ module QA
@commit_message = "This is a test commit" @commit_message = "This is a test commit"
@branch_name = 'master' @branch_name = 'master'
@new_branch = true @new_branch = true
@wait_for_push = true
end end
def repository_http_uri def repository_http_uri
...@@ -30,6 +33,7 @@ module QA ...@@ -30,6 +33,7 @@ module QA
def fabricate! def fabricate!
super super
project.visit! project.visit!
project.wait_for_push @commit_message if @wait_for_push
end end
end end
end end
......
...@@ -26,7 +26,6 @@ module QA ...@@ -26,7 +26,6 @@ module QA
push.file_content = "Test with unicode characters ❤✓€❄" push.file_content = "Test with unicode characters ❤✓€❄"
end end
Page::Project::Show.perform(&:wait_for_push)
merge_request.visit! merge_request.visit!
expect(page).to have_text('to be squashed') expect(page).to have_text('to be squashed')
...@@ -38,9 +37,7 @@ module QA ...@@ -38,9 +37,7 @@ module QA
merge_request.project.visit! merge_request.project.visit!
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = Page::Project::Show.act do repository.uri = merge_request.project.repository_http_location.uri
repository_clone_http_location.uri
end
repository.use_default_credentials repository.use_default_credentials
......
...@@ -23,7 +23,6 @@ module QA ...@@ -23,7 +23,6 @@ module QA
proj.name = 'project-qa-test' proj.name = 'project-qa-test'
proj.description = 'project for qa test' proj.description = 'project for qa test'
end end
project.visit!
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = project.repository_http_location.uri repository.uri = project.repository_http_location.uri
...@@ -53,7 +52,8 @@ module QA ...@@ -53,7 +52,8 @@ module QA
push_changes(third_branch) push_changes(third_branch)
end end
end end
Page::Project::Show.perform(&:wait_for_push) project.wait_for_push commit_message_of_third_branch
project.visit!
end end
it 'branches are correctly listed after CRUD operations' do it 'branches are correctly listed after CRUD operations' do
......
...@@ -3,22 +3,18 @@ ...@@ -3,22 +3,18 @@
module QA module QA
context 'Create' do context 'Create' do
describe 'Git clone over HTTP', :ldap_no_tls do describe 'Git clone over HTTP', :ldap_no_tls do
let(:location) do before(:all) do
Page::Project::Show.perform(&:repository_clone_http_location).uri
end
before do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials) Page::Main::Login.perform(&:sign_in_using_credentials)
project = Resource::Project.fabricate! do |scenario| @project = Resource::Project.fabricate! do |scenario|
scenario.name = 'project-with-code' scenario.name = 'project-with-code'
scenario.description = 'project for git clone tests' scenario.description = 'project for git clone tests'
end end
project.visit! @project.visit!
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location repository.uri = @project.repository_http_location.uri
repository.use_default_credentials repository.use_default_credentials
repository.act do repository.act do
...@@ -29,12 +25,12 @@ module QA ...@@ -29,12 +25,12 @@ module QA
push_changes push_changes
end end
end end
Page::Project::Show.perform(&:wait_for_push) @project.wait_for_push_new_branch
end end
it 'user performs a deep clone' do it 'user performs a deep clone' do
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location repository.uri = @project.repository_http_location.uri
repository.use_default_credentials repository.use_default_credentials
repository.clone repository.clone
...@@ -45,7 +41,7 @@ module QA ...@@ -45,7 +41,7 @@ module QA
it 'user performs a shallow clone' do it 'user performs a shallow clone' do
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location repository.uri = @project.repository_http_location.uri
repository.use_default_credentials repository.use_default_credentials
repository.shallow_clone repository.shallow_clone
......
...@@ -35,7 +35,7 @@ module QA ...@@ -35,7 +35,7 @@ module QA
end end
project.visit! project.visit!
Page::Project::Show.perform(&:wait_for_push) project.wait_for_push_new_branch
# Check that the push worked # Check that the push worked
expect(page).to have_content(file_name) expect(page).to have_content(file_name)
......
...@@ -70,7 +70,7 @@ module QA ...@@ -70,7 +70,7 @@ module QA
end end
project.visit! project.visit!
Page::Project::Show.perform(&:wait_for_push) project.wait_for_push_new_branch
# Check that the push worked # Check that the push worked
expect(page).to have_content(file_name) expect(page).to have_content(file_name)
......
...@@ -23,10 +23,7 @@ module QA ...@@ -23,10 +23,7 @@ module QA
push.project.visit! push.project.visit!
Page::Project::Show.perform do |page| Page::Project::Show.perform(&:wait_for_viewers_to_load)
page.wait_for_push
page.wait_for_viewers_to_load
end
expect(page).to have_content('README.md') expect(page).to have_content('README.md')
expect(page).to have_content('This is a test project') expect(page).to have_content('This is a test project')
......
...@@ -20,8 +20,6 @@ module QA ...@@ -20,8 +20,6 @@ module QA
end end
source_project_push.project.visit! source_project_push.project.visit!
Page::Project::Show.perform(&:wait_for_push)
Page::Project::Menu.perform(&:click_repository_settings) Page::Project::Menu.perform(&:click_repository_settings)
Page::Project::Settings::Repository.perform do |settings| Page::Project::Settings::Repository.perform do |settings|
settings.expand_mirroring_repositories do |mirror_settings| settings.expand_mirroring_repositories do |mirror_settings|
......
...@@ -31,7 +31,7 @@ module QA ...@@ -31,7 +31,7 @@ module QA
set_file_size_limit(5) set_file_size_limit(5)
expect(page).to have_content("Application settings saved successfully") expect(page).to have_content("Application settings saved successfully")
push = push_new_file('oversize_file_1.bin') push = push_new_file('oversize_file_1.bin', wait_for_push: true)
expect(push.output).not_to have_content 'remote: fatal: pack exceeds maximum allowed size' expect(push.output).not_to have_content 'remote: fatal: pack exceeds maximum allowed size'
end end
...@@ -39,7 +39,7 @@ module QA ...@@ -39,7 +39,7 @@ module QA
set_file_size_limit(1) set_file_size_limit(1)
expect(page).to have_content("Application settings saved successfully") expect(page).to have_content("Application settings saved successfully")
push = push_new_file('oversize_file_2.bin') push = push_new_file('oversize_file_2.bin', wait_for_push: false)
expect(push.output).to have_content 'remote: fatal: pack exceeds maximum allowed size' expect(push.output).to have_content 'remote: fatal: pack exceeds maximum allowed size'
end end
...@@ -55,7 +55,7 @@ module QA ...@@ -55,7 +55,7 @@ module QA
end end
end end
def push_new_file(file_name) def push_new_file(file_name, wait_for_push: true)
@project.visit! @project.visit!
Resource::Repository::ProjectPush.fabricate! do |p| Resource::Repository::ProjectPush.fabricate! do |p|
...@@ -63,6 +63,7 @@ module QA ...@@ -63,6 +63,7 @@ module QA
p.file_name = file_name p.file_name = file_name
p.file_content = SecureRandom.random_bytes(2000000) p.file_content = SecureRandom.random_bytes(2000000)
p.commit_message = 'Adding a new file' p.commit_message = 'Adding a new file'
p.wait_for_push = wait_for_push
end end
end end
end end
......
...@@ -5,7 +5,7 @@ module QA ...@@ -5,7 +5,7 @@ module QA
describe 'Git push over HTTP', :ldap_no_tls do describe 'Git push over HTTP', :ldap_no_tls do
it 'user pushes code to the repository' do it 'user pushes code to the repository' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
project_push = Resource::Repository::ProjectPush.fabricate! do |push| project_push = Resource::Repository::ProjectPush.fabricate! do |push|
push.file_name = 'README.md' push.file_name = 'README.md'
...@@ -13,7 +13,6 @@ module QA ...@@ -13,7 +13,6 @@ module QA
push.commit_message = 'Add README.md' push.commit_message = 'Add README.md'
end end
project_push.project.visit! project_push.project.visit!
Page::Project::Show.act { wait_for_push }
expect(page).to have_content('README.md') expect(page).to have_content('README.md')
expect(page).to have_content('This is a test project') expect(page).to have_content('This is a test project')
......
...@@ -63,6 +63,7 @@ module QA ...@@ -63,6 +63,7 @@ module QA
resource.commit_message = 'Add new_file.md' resource.commit_message = 'Add new_file.md'
resource.branch_name = branch_name resource.branch_name = branch_name
resource.new_branch = false resource.new_branch = false
resource.wait_for_push = false
end end
end end
end end
......
...@@ -10,7 +10,7 @@ module QA ...@@ -10,7 +10,7 @@ module QA
it 'user adds an ssh key and pushes code to the repository' do it 'user adds an ssh key and pushes code to the repository' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
key = Resource::SSHKey.fabricate! do |resource| key = Resource::SSHKey.fabricate! do |resource|
resource.title = key_title resource.title = key_title
...@@ -24,13 +24,12 @@ module QA ...@@ -24,13 +24,12 @@ module QA
end end
project_push.project.visit! project_push.project.visit!
Page::Project::Show.act { wait_for_push }
expect(page).to have_content('README.md') expect(page).to have_content('README.md')
expect(page).to have_content('Test Use SSH Key') expect(page).to have_content('Test Use SSH Key')
Page::Main::Menu.act { go_to_profile_settings } Page::Main::Menu.perform(&:go_to_profile_settings)
Page::Profile::Menu.act { click_ssh_keys } Page::Profile::Menu.perform(&:click_ssh_keys)
Page::Profile::SSHKeys.perform do |ssh_keys| Page::Profile::SSHKeys.perform do |ssh_keys|
ssh_keys.remove_key(key_title) ssh_keys.remove_key(key_title)
......
...@@ -11,7 +11,7 @@ module QA ...@@ -11,7 +11,7 @@ module QA
it 'users creates a pipeline which gets processed' do it 'users creates a pipeline which gets processed' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
project = Resource::Project.fabricate! do |project| project = Resource::Project.fabricate! do |project|
project.name = 'project-with-pipelines' project.name = 'project-with-pipelines'
...@@ -60,11 +60,9 @@ module QA ...@@ -60,11 +60,9 @@ module QA
EOF EOF
end end
Page::Project::Show.act { wait_for_push }
expect(page).to have_content('Add .gitlab-ci.yml') expect(page).to have_content('Add .gitlab-ci.yml')
Page::Project::Menu.act { click_ci_cd_pipelines } Page::Project::Menu.perform(&:click_ci_cd_pipelines)
expect(page).to have_content('All 1') expect(page).to have_content('All 1')
expect(page).to have_content('Add .gitlab-ci.yml') expect(page).to have_content('Add .gitlab-ci.yml')
...@@ -72,7 +70,7 @@ module QA ...@@ -72,7 +70,7 @@ module QA
puts 'Waiting for the runner to process the pipeline' puts 'Waiting for the runner to process the pipeline'
sleep 15 # Runner should process all jobs within 15 seconds. sleep 15 # Runner should process all jobs within 15 seconds.
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline)
Page::Project::Pipeline::Show.perform do |pipeline| Page::Project::Pipeline::Show.perform do |pipeline|
expect(pipeline).to be_running expect(pipeline).to be_running
......
...@@ -8,7 +8,7 @@ module QA ...@@ -8,7 +8,7 @@ module QA
describe 'Git clone using a deploy key' do describe 'Git clone using a deploy key' do
def login def login
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
end end
before(:all) do before(:all) do
...@@ -29,7 +29,7 @@ module QA ...@@ -29,7 +29,7 @@ module QA
resource.image = 'gitlab/gitlab-runner:ubuntu' resource.image = 'gitlab/gitlab-runner:ubuntu'
end end
Page::Main::Menu.act { sign_out } Page::Main::Menu.perform(&:sign_out)
end end
after(:all) do after(:all) do
...@@ -90,10 +90,9 @@ module QA ...@@ -90,10 +90,9 @@ module QA
sha1sum = Digest::SHA1.hexdigest(gitlab_ci) sha1sum = Digest::SHA1.hexdigest(gitlab_ci)
Page::Project::Show.act { wait_for_push } Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Menu.act { click_ci_cd_pipelines } Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline)
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Show.perform(&:go_to_first_job)
Page::Project::Pipeline::Show.act { go_to_first_job }
Page::Project::Job::Show.perform do |job| Page::Project::Job::Show.perform do |job|
expect(job).to be_successful, "Job status did not become \"passed\"." expect(job).to be_successful, "Job status did not become \"passed\"."
......
...@@ -8,7 +8,7 @@ module QA ...@@ -8,7 +8,7 @@ module QA
describe 'Auto DevOps support' do describe 'Auto DevOps support' do
def login def login
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
end end
[true, false].each do |rbac| [true, false].each do |rbac|
...@@ -38,8 +38,6 @@ module QA ...@@ -38,8 +38,6 @@ module QA
push.commit_message = 'Create Auto DevOps compatible rack application' push.commit_message = 'Create Auto DevOps compatible rack application'
end end
Page::Project::Show.act { wait_for_push }
# Create and connect K8s cluster # Create and connect K8s cluster
@cluster = Service::KubernetesCluster.new(rbac: rbac).create! @cluster = Service::KubernetesCluster.new(rbac: rbac).create!
kubernetes_cluster = Resource::KubernetesCluster.fabricate! do |cluster| kubernetes_cluster = Resource::KubernetesCluster.fabricate! do |cluster|
...@@ -53,7 +51,7 @@ module QA ...@@ -53,7 +51,7 @@ module QA
kubernetes_cluster.populate(:ingress_ip) kubernetes_cluster.populate(:ingress_ip)
@project.visit! @project.visit!
Page::Project::Menu.act { click_ci_cd_settings } Page::Project::Menu.perform(&:click_ci_cd_settings)
Page::Project::Settings::CICD.perform do |p| Page::Project::Settings::CICD.perform do |p|
p.enable_auto_devops p.enable_auto_devops
end end
...@@ -71,8 +69,8 @@ module QA ...@@ -71,8 +69,8 @@ module QA
it 'runs auto devops' do it 'runs auto devops' do
@project.visit! @project.visit!
Page::Project::Menu.act { click_ci_cd_pipelines } Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline)
Page::Project::Pipeline::Show.perform do |pipeline| Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('build') pipeline.go_to_job('build')
...@@ -101,7 +99,7 @@ module QA ...@@ -101,7 +99,7 @@ module QA
job.click_element(:pipeline_path) job.click_element(:pipeline_path)
end end
Page::Project::Menu.act { click_operations_environments } Page::Project::Menu.perform(&:click_operations_environments)
Page::Project::Operations::Environments::Index.perform do |index| Page::Project::Operations::Environments::Index.perform do |index|
index.go_to_environment('production') index.go_to_environment('production')
end end
...@@ -132,8 +130,8 @@ module QA ...@@ -132,8 +130,8 @@ module QA
end end
@project.visit! @project.visit!
Page::Project::Menu.act { click_ci_cd_pipelines } Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Index.perform(&:go_to_latest_pipeline)
Page::Project::Pipeline::Show.perform do |pipeline| Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('build') pipeline.go_to_job('build')
...@@ -162,7 +160,7 @@ module QA ...@@ -162,7 +160,7 @@ module QA
job.click_element(:pipeline_path) job.click_element(:pipeline_path)
end end
Page::Project::Menu.act { click_operations_environments } Page::Project::Menu.perform(&:click_operations_environments)
Page::Project::Operations::Environments::Index.perform do |index| Page::Project::Operations::Environments::Index.perform do |index|
index.go_to_environment('production') index.go_to_environment('production')
......
...@@ -10,15 +10,11 @@ module QA ...@@ -10,15 +10,11 @@ module QA
super super
end end
def wait(max: 60, time: 0.1, reload: true) def wait(max: 60, interval: 0.1, reload: true)
log("with wait: max #{max}; time #{time}; reload #{reload}") log("next wait uses reload: #{reload}")
now = Time.now # Logging of wait start/end/duration is handled by QA::Support::Waiter
element = super
log("ended wait after #{Time.now - now} seconds") super
element
end end
def scroll_to(selector, text: nil) def scroll_to(selector, text: nil)
......
# frozen_string_literal: true
module QA
module Support
module Waiter
module_function
def wait(max: 60, interval: 0.1)
QA::Runtime::Logger.debug("with wait: max #{max}; interval #{interval}")
start = Time.now
while Time.now - start < max
result = yield
if result
log_end(Time.now - start)
return result
end
sleep(interval)
end
log_end(Time.now - start)
false
end
def self.log_end(duration)
QA::Runtime::Logger.debug("ended wait after #{duration} seconds")
end
end
end
end
describe QA::Git::Repository do describe QA::Git::Repository do
include Support::StubENV include Helpers::StubENV
shared_context 'git directory' do shared_context 'git directory' do
let(:repository) { described_class.new } let(:repository) { described_class.new }
......
# Inspired by https://github.com/ljkbennett/stub_env/blob/master/lib/stub_env/helpers.rb # Inspired by https://github.com/ljkbennett/stub_env/blob/master/lib/stub_env/helpers.rb
module Support module Helpers
module StubENV module StubENV
def stub_env(key_or_hash, value = nil) def stub_env(key_or_hash, value = nil)
init_stub unless env_stubbed? init_stub unless env_stubbed?
......
...@@ -59,4 +59,34 @@ describe QA::Page::Base do ...@@ -59,4 +59,34 @@ describe QA::Page::Base do
end end
end end
end end
describe '#wait' do
subject { Class.new(described_class).new }
context 'when the condition is true' do
it 'does not refresh' do
expect(subject).not_to receive(:refresh)
subject.wait(max: 0.01) { true }
end
it 'returns true' do
expect(subject.wait(max: 0.1) { true }).to be_truthy
end
end
context 'when the condition is false' do
it 'refreshes' do
expect(subject).to receive(:refresh).at_least(:once)
subject.wait(max: 0.01) { false }
end
it 'returns false' do
allow(subject).to receive(:refresh)
expect(subject.wait(max: 0.01) { false }).to be_falsey
end
end
end
end end
...@@ -4,8 +4,6 @@ require 'capybara/dsl' ...@@ -4,8 +4,6 @@ require 'capybara/dsl'
require 'logger' require 'logger'
describe QA::Support::Page::Logging do describe QA::Support::Page::Logging do
include Support::StubENV
let(:page) { double.as_null_object } let(:page) { double.as_null_object }
before do before do
...@@ -30,12 +28,23 @@ describe QA::Support::Page::Logging do ...@@ -30,12 +28,23 @@ describe QA::Support::Page::Logging do
end end
it 'logs wait' do it 'logs wait' do
expect { subject.wait(max: 0) {} }
.to output(/next wait uses reload: true/).to_stdout_from_any_process
expect { subject.wait(max: 0) {} } expect { subject.wait(max: 0) {} }
.to output(/with wait/).to_stdout_from_any_process .to output(/with wait/).to_stdout_from_any_process
expect { subject.wait(max: 0) {} } expect { subject.wait(max: 0) {} }
.to output(/ended wait after .* seconds$/).to_stdout_from_any_process .to output(/ended wait after .* seconds$/).to_stdout_from_any_process
end end
it 'logs wait with reload false' do
expect { subject.wait(max: 0, reload: false) {} }
.to output(/next wait uses reload: false/).to_stdout_from_any_process
expect { subject.wait(max: 0, reload: false) {} }
.to output(/with wait/).to_stdout_from_any_process
expect { subject.wait(max: 0, reload: false) {} }
.to output(/ended wait after .* seconds$/).to_stdout_from_any_process
end
it 'logs scroll_to' do it 'logs scroll_to' do
expect { subject.scroll_to(:element) } expect { subject.scroll_to(:element) }
.to output(/scrolling to :element/).to_stdout_from_any_process .to output(/scrolling to :element/).to_stdout_from_any_process
......
# frozen_string_literal: true # frozen_string_literal: true
describe QA::Resource::Base do describe QA::Resource::Base do
include Support::StubENV include Helpers::StubENV
let(:resource) { spy('resource') } let(:resource) { spy('resource') }
let(:location) { 'http://location' } let(:location) { 'http://location' }
......
# frozen_string_literal: true
describe QA::Resource::Events::Base do
let(:resource) do
Class.new(QA::Resource::Base) do
def api_get_path
'/foo'
end
end
end
subject { resource.tap { |f| f.include(described_class) }.new }
describe "#events" do
it 'fetches all events when called without parameters' do
allow(subject).to receive(:parse_body).and_return('returned')
expect(subject).to receive(:api_get_from).with('/foo/events')
expect(subject.events).to eq('returned')
end
it 'fetches events with a specified action type' do
allow(subject).to receive(:parse_body).and_return('returned')
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed')
expect(subject.events(action: 'pushed')).to eq('returned')
end
end
end
# frozen_string_literal: true
describe QA::Resource::Events::Project do
let(:resource) do
Class.new(QA::Resource::Base) do
def api_get_path
'/foo'
end
end
end
let(:all_events) do
[
{
"action_name": "pushed",
"push_data": {
"commit_title": "foo commit"
}
},
{
"action_name": "pushed",
"push_data": {
"ref": "master"
}
},
{
"action_name": "pushed",
"push_data": {
"ref": "another-branch"
}
}
]
end
before do
allow(subject).to receive(:max_wait).and_return(0.01)
allow(subject).to receive(:parse_body).and_return(all_events)
end
subject { resource.tap { |f| f.include(described_class) }.new }
describe "#wait_for_push" do
it 'waits for a push with a specified commit message' do
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed')
expect { subject.wait_for_push('foo commit') }.not_to raise_error
end
it 'raises an error if a push with the specified commit message is not found' do
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed').at_least(:once)
expect { subject.wait_for_push('bar') }.to raise_error(QA::Resource::Events::EventNotFoundError)
end
end
describe "#wait_for_push_new_branch" do
it 'waits for a push to master if no branch is given' do
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed')
expect { subject.wait_for_push_new_branch }.not_to raise_error
end
it 'waits for a push to the given branch' do
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed')
expect { subject.wait_for_push_new_branch('another-branch') }.not_to raise_error
end
it 'raises an error if a push with the specified branch is not found' do
expect(subject).to receive(:api_get_from).with('/foo/events?action=pushed').at_least(:once)
expect { subject.wait_for_push_new_branch('bar') }.to raise_error(QA::Resource::Events::EventNotFoundError)
end
end
end
describe QA::Runtime::API::Client do describe QA::Runtime::API::Client do
include Support::StubENV include Helpers::StubENV
describe 'initialization' do describe 'initialization' do
it 'defaults to :gitlab address' do it 'defaults to :gitlab address' do
......
# frozen_string_literal: true # frozen_string_literal: true
describe QA::Runtime::Env do describe QA::Runtime::Env do
include Support::StubENV include Helpers::StubENV
shared_examples 'boolean method' do |**kwargs| shared_examples 'boolean method' do |**kwargs|
it_behaves_like 'boolean method with parameter', kwargs it_behaves_like 'boolean method with parameter', kwargs
......
require_relative '../qa' require_relative '../qa'
Dir[::File.join(__dir__, 'support', '**', '*.rb')].each { |f| require f } %w[helpers shared_examples].each do |d|
Dir[::File.join(__dir__, d, '**', '*.rb')].each { |f| require f }
end
RSpec.configure do |config| RSpec.configure do |config|
ServerNotRespondingError = Class.new(RuntimeError) ServerNotRespondingError = Class.new(RuntimeError)
......
# frozen_string_literal: true
require 'logger'
describe QA::Support::Waiter do
before do
logger = ::Logger.new $stdout
logger.level = ::Logger::DEBUG
QA::Runtime::Logger.logger = logger
end
describe '.wait' do
context 'when the condition is true' do
it 'logs the start' do
expect { subject.wait(max: 0) {} }
.to output(/with wait: max 0; interval 0.1/).to_stdout_from_any_process
end
it 'logs the end' do
expect { subject.wait(max: 0) {} }
.to output(/ended wait after .* seconds$/).to_stdout_from_any_process
end
end
context 'when the condition is false' do
it 'logs the start' do
expect { subject.wait(max: 0) { false } }
.to output(/with wait: max 0; interval 0.1/).to_stdout_from_any_process
end
it 'logs the end' do
expect { subject.wait(max: 0) { false } }
.to output(/ended wait after .* seconds$/).to_stdout_from_any_process
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment