diff options
Diffstat (limited to 'qa')
26 files changed, 361 insertions, 103 deletions
@@ -46,10 +46,13 @@ module QA autoload :Runner, 'qa/factory/resource/runner' autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token' autoload :KubernetesCluster, 'qa/factory/resource/kubernetes_cluster' + autoload :Wiki, 'qa/factory/resource/wiki' end module Repository autoload :Push, 'qa/factory/repository/push' + autoload :ProjectPush, 'qa/factory/repository/project_push' + autoload :WikiPush, 'qa/factory/repository/wiki_push' end module Settings @@ -165,6 +168,16 @@ module QA autoload :Show, 'qa/page/project/operations/kubernetes/show' end end + + module Wiki + autoload :Edit, 'qa/page/project/wiki/edit' + autoload :New, 'qa/page/project/wiki/new' + autoload :Show, 'qa/page/project/wiki/show' + end + end + + module Shared + autoload :ClonePanel, 'qa/page/shared/clone_panel' end module Profile diff --git a/qa/qa/factory/repository/project_push.rb b/qa/qa/factory/repository/project_push.rb new file mode 100644 index 00000000000..48674c08a8d --- /dev/null +++ b/qa/qa/factory/repository/project_push.rb @@ -0,0 +1,34 @@ +module QA + module Factory + module Repository + class ProjectPush < Factory::Repository::Push + dependency Factory::Resource::Project, as: :project do |project| + project.name = 'project-with-code' + project.description = 'Project with repository' + end + + product :output do |factory| + factory.output + end + + def initialize + @file_name = 'file.txt' + @file_content = '# This is test project' + @commit_message = "This is a test commit" + @branch_name = 'master' + @new_branch = true + end + + def repository_uri + @repository_uri ||= begin + project.visit! + Page::Project::Show.act do + choose_repository_clone_http + repository_location.uri + end + end + end + end + end + end +end diff --git a/qa/qa/factory/repository/push.rb b/qa/qa/factory/repository/push.rb index 7c0d580c5ca..4f97e65b091 100644 --- a/qa/qa/factory/repository/push.rb +++ b/qa/qa/factory/repository/push.rb @@ -5,25 +5,17 @@ module QA module Repository class Push < Factory::Base attr_accessor :file_name, :file_content, :commit_message, - :branch_name, :new_branch, :output + :branch_name, :new_branch, :output, :repository_uri attr_writer :remote_branch - dependency Factory::Resource::Project, as: :project do |project| - project.name = 'project-with-code' - project.description = 'Project with repository' - end - - product :output do |factory| - factory.output - end - def initialize @file_name = 'file.txt' - @file_content = '# This is test project' + @file_content = '# This is test file' @commit_message = "This is a test commit" @branch_name = 'master' @new_branch = true + @repository_uri = "" end def remote_branch @@ -37,14 +29,8 @@ module QA end def fabricate! - project.visit! - Git::Repository.perform do |repository| - repository.uri = Page::Project::Show.act do - choose_repository_clone_http - repository_location.uri - end - + repository.uri = repository_uri repository.use_default_credentials repository.clone repository.configure_identity('GitLab QA', 'root@gitlab.com') diff --git a/qa/qa/factory/repository/wiki_push.rb b/qa/qa/factory/repository/wiki_push.rb new file mode 100644 index 00000000000..fb7c2bb660d --- /dev/null +++ b/qa/qa/factory/repository/wiki_push.rb @@ -0,0 +1,32 @@ +module QA + module Factory + module Repository + class WikiPush < Factory::Repository::Push + dependency Factory::Resource::Wiki, as: :wiki do |wiki| + wiki.title = 'Home' + wiki.content = '# My First Wiki Content' + wiki.message = 'Update home' + end + + def initialize + @file_name = 'Home.md' + @file_content = '# Welcome to My Wiki' + @commit_message = 'Updating Home Page' + @branch_name = 'master' + @new_branch = false + end + + def repository_uri + @repository_uri ||= begin + wiki.visit! + Page::Project::Wiki::Show.act do + go_to_clone_repository + choose_repository_clone_http + repository_location.uri + end + end + end + end + end + end +end diff --git a/qa/qa/factory/resource/branch.rb b/qa/qa/factory/resource/branch.rb index 4cabe7eab45..7fb0633ec90 100644 --- a/qa/qa/factory/resource/branch.rb +++ b/qa/qa/factory/resource/branch.rb @@ -31,13 +31,13 @@ module QA def fabricate! project.visit! - Factory::Repository::Push.fabricate! do |resource| + Factory::Repository::ProjectPush.fabricate! do |resource| resource.project = project resource.file_name = 'kick-off.txt' resource.commit_message = 'First commit' end - branch = Factory::Repository::Push.fabricate! do |resource| + branch = Factory::Repository::ProjectPush.fabricate! do |resource| resource.project = project resource.file_name = 'README.md' resource.commit_message = 'Add readme' diff --git a/qa/qa/factory/resource/merge_request.rb b/qa/qa/factory/resource/merge_request.rb index 7588ac5735d..24d3597d993 100644 --- a/qa/qa/factory/resource/merge_request.rb +++ b/qa/qa/factory/resource/merge_request.rb @@ -21,14 +21,14 @@ module QA project.name = 'project-with-merge-request' end - dependency Factory::Repository::Push, as: :target do |push, factory| + dependency Factory::Repository::ProjectPush, as: :target do |push, factory| factory.project.visit! push.project = factory.project push.branch_name = 'master' push.remote_branch = factory.target_branch end - dependency Factory::Repository::Push, as: :source do |push, factory| + dependency Factory::Repository::ProjectPush, as: :source do |push, factory| push.project = factory.project push.branch_name = factory.target_branch push.remote_branch = factory.source_branch diff --git a/qa/qa/factory/resource/wiki.rb b/qa/qa/factory/resource/wiki.rb new file mode 100644 index 00000000000..cc200a512d5 --- /dev/null +++ b/qa/qa/factory/resource/wiki.rb @@ -0,0 +1,25 @@ +module QA + module Factory + module Resource + class Wiki < Factory::Base + attr_accessor :title, :content, :message + + dependency Factory::Resource::Project, as: :project do |project| + project.name = 'project-for-wikis' + project.description = 'project for adding wikis' + end + + def fabricate! + Page::Menu::Side.act { click_wiki } + Page::Project::Wiki::New.perform do |page| + page.go_to_create_first_page + page.set_title(@title) + page.set_content(@content) + page.set_message(@message) + page.create_new_page + end + end + end + end + end +end diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index 596205fe540..26c99efc53d 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -26,53 +26,58 @@ module QA end def initialize + # The login page is usually the entry point for all the scenarios so + # we need to wait for the instance to start. That said, in some cases + # we are already logged-in so we check both cases here. wait(max: 500) do - page.has_css?('.application') + page.has_css?('.login-page') || + Page::Menu::Main.act { has_personal_area? } end end - def set_initial_password_if_present - 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' + def sign_in_using_credentials + # Don't try to log-in if we're already logged-in + return if Page::Menu::Main.act { has_personal_area? } + + using_wait_time 0 do + set_initial_password_if_present + + if Runtime::User.ldap_user? + sign_in_using_ldap_credentials + else + sign_in_using_gitlab_credentials + end end end - def sign_in_using_credentials - if Runtime::User.ldap_user? - sign_in_using_ldap_credentials - else - sign_in_using_gitlab_credentials - end + def self.path + '/users/sign_in' end - def sign_in_using_ldap_credentials - using_wait_time 0 do - set_initial_password_if_present + private - click_link 'LDAP' + def sign_in_using_ldap_credentials + click_link 'LDAP' - fill_in :username, with: Runtime::User.ldap_username - fill_in :password, with: Runtime::User.ldap_password - click_button 'Sign in' - end + fill_in :username, with: Runtime::User.ldap_username + fill_in :password, with: Runtime::User.ldap_password + click_button 'Sign in' end def sign_in_using_gitlab_credentials - using_wait_time 0 do - set_initial_password_if_present - - click_link 'Standard' if page.has_content?('LDAP') + click_link 'Standard' if page.has_content?('LDAP') - fill_in :user_login, with: Runtime::User.name - fill_in :user_password, with: Runtime::User.password - click_button 'Sign in' - end + fill_in :user_login, with: Runtime::User.name + fill_in :user_password, with: Runtime::User.password + click_button 'Sign in' end - def self.path - '/users/sign_in' + def set_initial_password_if_present + return unless 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 end end diff --git a/qa/qa/page/menu/main.rb b/qa/qa/page/menu/main.rb index 644fedecc90..fda9c45c091 100644 --- a/qa/qa/page/menu/main.rb +++ b/qa/qa/page/menu/main.rb @@ -55,7 +55,8 @@ module QA end def has_personal_area? - page.has_selector?('.qa-user-avatar') + # No need to wait, either we're logged-in, or not. + using_wait_time(0) { page.has_selector?('.qa-user-avatar') } end private diff --git a/qa/qa/page/menu/side.rb b/qa/qa/page/menu/side.rb index 3630b7e8568..6bf4825cf00 100644 --- a/qa/qa/page/menu/side.rb +++ b/qa/qa/page/menu/side.rb @@ -13,6 +13,7 @@ module QA element :top_level_items, '.sidebar-top-level-items' element :operations_section, "class: 'shortcuts-operations'" element :activity_link, "title: 'Activity'" + element :wiki_link_text, "Wiki" end view 'app/assets/javascripts/fly_out_nav.js' do @@ -61,6 +62,12 @@ module QA end end + def click_wiki + within_sidebar do + click_link('Wiki') + end + end + private def hover_settings diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb index 5bbef040330..1406edece17 100644 --- a/qa/qa/page/project/show.rb +++ b/qa/qa/page/project/show.rb @@ -2,11 +2,7 @@ module QA module Page module Project class Show < Page::Base - view 'app/views/shared/_clone_panel.html.haml' do - element :clone_dropdown - element :clone_options_dropdown, '.clone-options-dropdown' - element :project_repository_location, 'text_field_tag :project_clone' - end + include Page::Shared::ClonePanel view 'app/views/projects/_last_push.html.haml' do element :create_merge_request @@ -26,21 +22,6 @@ module QA element :branches_dropdown end - def choose_repository_clone_http - choose_repository_clone('HTTP', 'http') - end - - def choose_repository_clone_ssh - # It's not always beginning with ssh:// so detecting with @ - # would be more reliable because ssh would always contain it. - # We can't use .git because HTTP also contain that part. - choose_repository_clone('SSH', '@') - end - - def repository_location - Git::Location.new(find('#project_clone').value) - end - def project_name find('.qa-project-name').text end @@ -65,31 +46,11 @@ module QA click_element :create_merge_request end - def wait_for_push - sleep 5 - refresh - end - def go_to_new_issue click_element :new_menu_toggle click_link 'New issue' end - - private - - def choose_repository_clone(kind, detect_text) - wait(reload: false) do - click_element :clone_dropdown - - page.within('.clone-options-dropdown') do - click_link(kind) - end - - # Ensure git clone textbox was updated - repository_location.git_uri.include?(detect_text) - end - end end end end diff --git a/qa/qa/page/project/wiki/edit.rb b/qa/qa/page/project/wiki/edit.rb new file mode 100644 index 00000000000..6fa45569cc0 --- /dev/null +++ b/qa/qa/page/project/wiki/edit.rb @@ -0,0 +1,27 @@ +module QA + module Page + module Project + module Wiki + class Edit < Page::Base + view 'app/views/projects/wikis/_main_links.html.haml' do + element :new_page_link, 'New page' + element :page_history_link, 'Page history' + element :edit_page_link, 'Edit' + end + + def go_to_new_page + click_on 'New page' + end + + def got_to_view_history_page + click_on 'Page history' + end + + def go_to_edit_page + click_on 'Edit' + end + end + end + end + end +end diff --git a/qa/qa/page/project/wiki/new.rb b/qa/qa/page/project/wiki/new.rb new file mode 100644 index 00000000000..415b3835538 --- /dev/null +++ b/qa/qa/page/project/wiki/new.rb @@ -0,0 +1,45 @@ +module QA + module Page + module Project + module Wiki + class New < Page::Base + view 'app/views/projects/wikis/_form.html.haml' do + element :wiki_title_textbox, 'text_field :title' + element :wiki_content_textarea, "render 'projects/zen', f: f, attr: :content" + element :wiki_message_textbox, 'text_field :message' + element :save_changes_button, 'submit _("Save changes")' + element :create_page_button, 'submit s_("Wiki|Create page")' + end + + view 'app/views/shared/empty_states/_wikis.html.haml' do + element :create_link, 'Create your first page' + end + + def go_to_create_first_page + click_link 'Create your first page' + end + + def set_title(title) + fill_in 'wiki_title', with: title + end + + def set_content(content) + fill_in 'wiki_content', with: content + end + + def set_message(message) + fill_in 'wiki_message', with: message + end + + def save_changes + click_on 'Save changes' + end + + def create_new_page + click_on 'Create page' + end + end + end + end + end +end diff --git a/qa/qa/page/project/wiki/show.rb b/qa/qa/page/project/wiki/show.rb new file mode 100644 index 00000000000..044e514bab3 --- /dev/null +++ b/qa/qa/page/project/wiki/show.rb @@ -0,0 +1,19 @@ +module QA + module Page + module Project + module Wiki + class Show < Page::Base + include Page::Shared::ClonePanel + + view 'app/views/projects/wikis/pages.html.haml' do + element :clone_repository_link, 'Clone repository' + end + + def go_to_clone_repository + click_on 'Clone repository' + end + end + end + end + end +end diff --git a/qa/qa/page/shared/clone_panel.rb b/qa/qa/page/shared/clone_panel.rb new file mode 100644 index 00000000000..73e3dff956d --- /dev/null +++ b/qa/qa/page/shared/clone_panel.rb @@ -0,0 +1,50 @@ +module QA + module Page + module Shared + module ClonePanel + def self.included(base) + base.view 'app/views/shared/_clone_panel.html.haml' do + element :clone_dropdown + element :clone_options_dropdown, '.clone-options-dropdown' + element :project_repository_location, 'text_field_tag :project_clone' + end + end + + def choose_repository_clone_http + choose_repository_clone('HTTP', 'http') + end + + def choose_repository_clone_ssh + # It's not always beginning with ssh:// so detecting with @ + # would be more reliable because ssh would always contain it. + # We can't use .git because HTTP also contain that part. + choose_repository_clone('SSH', '@') + end + + def repository_location + Git::Location.new(find('#project_clone').value) + end + + def wait_for_push + sleep 5 + refresh + end + + private + + def choose_repository_clone(kind, detect_text) + wait(reload: false) do + click_element :clone_dropdown + + page.within('.clone-options-dropdown') do + click_link(kind) + end + + # Ensure git clone textbox was updated + repository_location.git_uri.include?(detect_text) + end + end + end + end + end +end diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb index 81d00d45753..2126ce6b234 100644 --- a/qa/qa/runtime/env.rb +++ b/qa/qa/runtime/env.rb @@ -3,6 +3,8 @@ module QA module Env extend self + attr_writer :user_type + # set to 'false' to have Chrome run visibly instead of headless def chrome_headless? (ENV['CHROME_HEADLESS'] =~ /^(false|no|0)$/i) != 0 @@ -20,7 +22,9 @@ module QA # By default, "standard" denotes a standard GitLab user login. # Set this to "ldap" if the user should be logged in via LDAP. def user_type - (ENV['GITLAB_USER_TYPE'] || 'standard').tap do |type| + return @user_type if defined?(@user_type) # rubocop:disable Gitlab/ModuleWithInstanceVariables + + ENV.fetch('GITLAB_USER_TYPE', 'standard').tap do |type| unless %w(ldap standard).include?(type) raise ArgumentError.new("Invalid user type '#{type}': must be 'ldap' or 'standard'") end diff --git a/qa/qa/specs/features/login/ldap_spec.rb b/qa/qa/specs/features/login/ldap_spec.rb index ac2bd5a3c39..737f4d10053 100644 --- a/qa/qa/specs/features/login/ldap_spec.rb +++ b/qa/qa/specs/features/login/ldap_spec.rb @@ -1,8 +1,12 @@ module QA feature 'LDAP user login', :ldap do + before do + Runtime::Env.user_type = 'ldap' + end + scenario 'user logs in using LDAP credentials' do Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.act { sign_in_using_ldap_credentials } + 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/merge_request/rebase_spec.rb b/qa/qa/specs/features/merge_request/rebase_spec.rb index 2a44d42af6f..6a0ed4592c4 100644 --- a/qa/qa/specs/features/merge_request/rebase_spec.rb +++ b/qa/qa/specs/features/merge_request/rebase_spec.rb @@ -16,7 +16,7 @@ module QA merge_request.title = 'Needs rebasing' end - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.project = project push.file_name = "other.txt" push.file_content = "New file added!" diff --git a/qa/qa/specs/features/merge_request/squash_spec.rb b/qa/qa/specs/features/merge_request/squash_spec.rb index dbbdf852a38..b68704154cf 100644 --- a/qa/qa/specs/features/merge_request/squash_spec.rb +++ b/qa/qa/specs/features/merge_request/squash_spec.rb @@ -13,7 +13,7 @@ module QA merge_request.title = 'Squashing commits' end - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.project = project push.commit_message = 'to be squashed' push.branch_name = merge_request.source_branch diff --git a/qa/qa/specs/features/project/activity_spec.rb b/qa/qa/specs/features/project/activity_spec.rb index ba94ce8cf28..07ac7321aa2 100644 --- a/qa/qa/specs/features/project/activity_spec.rb +++ b/qa/qa/specs/features/project/activity_spec.rb @@ -4,7 +4,7 @@ module QA Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.act { sign_in_using_credentials } - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' push.file_content = '# This is a test project' push.commit_message = 'Add README.md' diff --git a/qa/qa/specs/features/project/auto_devops_spec.rb b/qa/qa/specs/features/project/auto_devops_spec.rb index 202a847d1a5..c50a13432f5 100644 --- a/qa/qa/specs/features/project/auto_devops_spec.rb +++ b/qa/qa/specs/features/project/auto_devops_spec.rb @@ -16,7 +16,7 @@ module QA end # Create Auto Devops compatible repo - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.project = project push.directory = Pathname .new(__dir__) diff --git a/qa/qa/specs/features/project/deploy_key_clone_spec.rb b/qa/qa/specs/features/project/deploy_key_clone_spec.rb index 46b3e38c1c5..10e4cbb6906 100644 --- a/qa/qa/specs/features/project/deploy_key_clone_spec.rb +++ b/qa/qa/specs/features/project/deploy_key_clone_spec.rb @@ -75,7 +75,7 @@ module QA - docker YAML - Factory::Repository::Push.fabricate! do |resource| + Factory::Repository::ProjectPush.fabricate! do |resource| resource.project = @project resource.file_name = '.gitlab-ci.yml' resource.commit_message = 'Add .gitlab-ci.yml' diff --git a/qa/qa/specs/features/project/pipelines_spec.rb b/qa/qa/specs/features/project/pipelines_spec.rb index 74f6474443d..bdb3d671516 100644 --- a/qa/qa/specs/features/project/pipelines_spec.rb +++ b/qa/qa/specs/features/project/pipelines_spec.rb @@ -40,7 +40,7 @@ module QA runner.tags = %w[qa test] end - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.project = project push.file_name = '.gitlab-ci.yml' push.commit_message = 'Add .gitlab-ci.yml' diff --git a/qa/qa/specs/features/project/wikis_spec.rb b/qa/qa/specs/features/project/wikis_spec.rb new file mode 100644 index 00000000000..49290a1a896 --- /dev/null +++ b/qa/qa/specs/features/project/wikis_spec.rb @@ -0,0 +1,45 @@ +module QA + feature 'Wiki Functionality', :core do + def login + Runtime::Browser.visit(:gitlab, Page::Main::Login) + Page::Main::Login.act { sign_in_using_credentials } + end + + def validate_content(content) + expect(page).to have_content('Wiki was successfully updated') + expect(page).to have_content(/#{content}/) + end + + before do + login + end + + scenario 'User creates, edits, clones, and pushes to the wiki' do + wiki = Factory::Resource::Wiki.fabricate! do |resource| + resource.title = 'Home' + resource.content = '# My First Wiki Content' + resource.message = 'Update home' + end + + validate_content('My First Wiki Content') + + Page::Project::Wiki::Edit.act { go_to_edit_page } + Page::Project::Wiki::New.perform do |page| + page.set_content("My Second Wiki Content") + page.save_changes + end + + validate_content('My Second Wiki Content') + + Factory::Repository::WikiPush.fabricate! do |push| + push.wiki = wiki + push.file_name = 'Home.md' + push.file_content = '# My Third Wiki Content' + push.commit_message = 'Update Home.md' + end + Page::Menu::Side.act { click_wiki } + + expect(page).to have_content('My Third Wiki Content') + end + end +end diff --git a/qa/qa/specs/features/repository/protected_branches_spec.rb b/qa/qa/specs/features/repository/protected_branches_spec.rb index 491675875b9..ec3802e7a76 100644 --- a/qa/qa/specs/features/repository/protected_branches_spec.rb +++ b/qa/qa/specs/features/repository/protected_branches_spec.rb @@ -56,7 +56,7 @@ module QA end def push_new_file(branch) - Factory::Repository::Push.fabricate! do |resource| + Factory::Repository::ProjectPush.fabricate! do |resource| resource.project = project resource.file_name = 'new_file.md' resource.file_content = '# This is a new file' diff --git a/qa/qa/specs/features/repository/push_spec.rb b/qa/qa/specs/features/repository/push_spec.rb index 51d9c2c7fd2..16aaa2e6762 100644 --- a/qa/qa/specs/features/repository/push_spec.rb +++ b/qa/qa/specs/features/repository/push_spec.rb @@ -5,7 +5,7 @@ module QA Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.act { sign_in_using_credentials } - Factory::Repository::Push.fabricate! do |push| + Factory::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' push.file_content = '# This is a test project' push.commit_message = 'Add README.md' |