Commit 8d691856 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'qa/gb/selenium-handle-domain-sessions' into 'master'

Handle domain sessions better in QA scenarios

Closes gitlab-qa#102

See merge request gitlab-org/gitlab-ce!15452
parents ab0d5e27 9ac8bb08
......@@ -9,6 +9,7 @@ module QA
autoload :User, 'qa/runtime/user'
autoload :Namespace, 'qa/runtime/namespace'
autoload :Scenario, 'qa/runtime/scenario'
autoload :Browser, 'qa/runtime/browser'
end
##
......@@ -69,7 +70,6 @@ module QA
autoload :Base, 'qa/page/base'
module Main
autoload :Entry, 'qa/page/main/entry'
autoload :Login, 'qa/page/main/login'
autoload :Menu, 'qa/page/main/menu'
autoload :OAuth, 'qa/page/main/oauth'
......
......@@ -10,6 +10,18 @@ module QA
visit current_url
end
def wait(css = '.application', time: 60)
Time.now.tap do |start|
while Time.now - start < time
break if page.has_css?(css, wait: 5)
refresh
end
end
yield if block_given?
end
def scroll_to(selector, text: nil)
page.execute_script <<~JS
var elements = Array.from(document.querySelectorAll('#{selector}'));
......@@ -24,6 +36,10 @@ module QA
page.within(selector) { yield } if block_given?
end
def self.path
raise NotImplementedError
end
end
end
end
module QA
module Page
module Main
class Entry < Page::Base
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
while Time.now - start < 240
break if page.has_css?('.application', wait: 10)
refresh
end
end
end
end
end
end
......@@ -2,6 +2,10 @@ module QA
module Page
module Main
class Login < Page::Base
def initialize
wait('.application', time: 500)
end
def sign_in_using_credentials
if page.has_content?('Change your password')
fill_in :user_password, with: Runtime::User.password
......@@ -13,6 +17,10 @@ module QA
fill_in :user_password, with: Runtime::User.password
click_button 'Sign in'
end
def self.path
'/users/sign_in'
end
end
end
end
......
......@@ -2,10 +2,6 @@ module QA
module Page
module Mattermost
class Login < Page::Base
def initialize
visit(Runtime::Scenario.mattermost_address + '/login')
end
def sign_in_using_oauth
click_link class: 'btn btn-custom-login gitlab'
......@@ -13,6 +9,10 @@ module QA
click_button 'Authorize'
end
end
def self.path
'/login'
end
end
end
end
......
......@@ -3,37 +3,39 @@ require 'capybara/rspec'
require 'capybara-screenshot/rspec'
require 'selenium-webdriver'
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/LineLength
module QA
module Specs
class Config < Scenario::Template
include Scenario::Actable
module Runtime
class Browser
include QA::Scenario::Actable
def perform
configure_rspec!
configure_capybara!
def initialize
self.class.configure!
end
def configure_rspec!
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
##
# Visit a page that belongs to a GitLab instance under given address.
#
# Example:
#
# visit(:gitlab, Page::Main::Login)
# visit('http://gitlab.example/users/sign_in')
#
# In case of an address that is a symbol we will try to guess address
# based on `Runtime::Scenario#something_address`.
#
def visit(address, page, &block)
Browser::Session.new(address, page).tap do |session|
session.perform(&block)
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.order = :random
Kernel.srand config.seed
config.formatter = :documentation
config.color = true
end
def self.visit(address, page, &block)
new.visit(address, page, &block)
end
def configure_capybara!
def self.configure!
return if Capybara.drivers.include?(:chrome)
Capybara.register_driver :chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
......@@ -53,11 +55,55 @@ module QA
config.default_driver = :chrome
config.javascript_driver = :chrome
config.default_max_wait_time = 10
# https://github.com/mattheworiordan/capybara-screenshot/issues/164
config.save_path = 'tmp'
end
end
class Session
include Capybara::DSL
def initialize(instance, page = nil)
@instance = instance
@address = host + page&.path
end
def host
if @instance.is_a?(Symbol)
Runtime::Scenario.send("#{@instance}_address")
else
@instance.to_s
end
end
def perform(&block)
visit(@address)
yield if block_given?
rescue
raise if block.nil?
# RSpec examples will take care of screenshots on their own
#
unless block.binding.receiver.is_a?(RSpec::Core::ExampleGroup)
screenshot_and_save_page
end
raise
ensure
clear! if block_given?
end
##
# Selenium allows to reset session cookies for current domain only.
#
# See gitlab-org/gitlab-qa#102
#
def clear!
visit(@address)
reset_session!
end
end
end
end
end
......@@ -8,7 +8,6 @@ module QA
include Bootable
def perform(address, *files)
Specs::Config.act { configure_capybara! }
Runtime::Scenario.define(:gitlab_address, address)
##
......
......@@ -6,7 +6,6 @@ module QA
def perform(*traits)
raise ArgumentError unless traits.include?(:enabled)
Page::Main::Entry.act { visit_login_page }
Page::Main::Login.act { sign_in_using_credentials }
Page::Main::Menu.act { go_to_admin_area }
Page::Admin::Menu.act { go_to_settings }
......
module QA
feature 'standard root login', :core do
feature 'standard user login', :core do
scenario 'user logs in using credentials' do
Page::Main::Entry.act { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
# TODO, since `Signed in successfully` message was removed
......
module QA
feature 'create a new group', :mattermost do
scenario 'creating a group with a mattermost team' do
Page::Main::Entry.act { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
Page::Main::Menu.act { go_to_groups }
......
module QA
feature 'logging in to Mattermost', :mattermost do
scenario 'can use gitlab oauth' do
Page::Main::Entry.act { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login) do
Page::Main::Login.act { sign_in_using_credentials }
Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) do
Page::Mattermost::Login.act { sign_in_using_oauth }
Page::Mattermost::Main.perform do |page|
expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/)
end
end
##
# TODO, temporary workaround for gitlab-org/gitlab-qa#102.
#
after do
visit Runtime::Scenario.mattermost_address
reset_session!
visit Runtime::Scenario.gitlab_address
reset_session!
end
end
end
end
module QA
feature 'create a new project', :core do
scenario 'user creates a new project' do
Page::Main::Entry.act { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |project|
......
......@@ -9,7 +9,7 @@ module QA
end
before do
Page::Main::Entry.act { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |scenario|
......
......@@ -2,7 +2,7 @@ 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 { visit_login_page }
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
Scenario::Gitlab::Project::Create.perform do |scenario|
......
......@@ -17,7 +17,7 @@ module QA
tags.to_a.each { |tag| args.push(['-t', tag.to_s]) }
args.push(files)
Specs::Config.perform
Runtime::Browser.configure!
RSpec::Core::Runner.run(args.flatten, $stderr, $stdout).tap do |status|
abort if status.nonzero?
......
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