summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/invites_spec.rb112
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb1
-rw-r--r--spec/features/projects/commit/comments/user_adds_comment_spec.rb170
-rw-r--r--spec/features/projects/commit/comments/user_deletes_comments_spec.rb37
-rw-r--r--spec/features/projects/commit/comments/user_edits_comments_spec.rb42
-rw-r--r--spec/features/projects/commit/user_comments_on_commit_spec.rb110
-rw-r--r--spec/features/projects/merge_requests/user_creates_merge_request_spec.rb80
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb23
-rw-r--r--spec/features/projects/wiki/user_deletes_wiki_page_spec.rb3
9 files changed, 441 insertions, 137 deletions
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index e4be6193b8b..a986ddc4abc 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -5,18 +5,41 @@ describe 'Invites' do
let(:owner) { create(:user, name: 'John Doe') }
let(:group) { create(:group, name: 'Owned') }
let(:project) { create(:project, :repository, namespace: group) }
- let(:invite) { group.group_members.invite.last }
+ let(:group_invite) { group.group_members.invite.last }
before do
project.add_master(owner)
group.add_user(owner, Gitlab::Access::OWNER)
group.add_developer('user@example.com', owner)
- invite.generate_invite_token!
+ group_invite.generate_invite_token!
+ end
+
+ def confirm_email_and_sign_in(new_user)
+ new_user_token = User.find_by_email(new_user.email).confirmation_token
+
+ visit user_confirmation_path(confirmation_token: new_user_token)
+ fill_in_sign_in_form(new_user)
+ end
+
+ def fill_in_sign_up_form(new_user)
+ fill_in 'new_user_name', with: new_user.name
+ fill_in 'new_user_username', with: new_user.username
+ fill_in 'new_user_email', with: new_user.email
+ fill_in 'new_user_email_confirmation', with: new_user.email
+ fill_in 'new_user_password', with: new_user.password
+ click_button "Register"
+ end
+
+ def fill_in_sign_in_form(user)
+ fill_in 'user_login', with: user.email
+ fill_in 'user_password', with: user.password
+ check 'user_remember_me'
+ click_button 'Sign in'
end
context 'when signed out' do
before do
- visit invite_path(invite.raw_invite_token)
+ visit invite_path(group_invite.raw_invite_token)
end
it 'renders sign in page with sign in notice' do
@@ -25,12 +48,9 @@ describe 'Invites' do
end
it 'sign in and redirects to invitation page' do
- fill_in 'user_login', with: user.email
- fill_in 'user_password', with: user.password
- check 'user_remember_me'
- click_button 'Sign in'
+ fill_in_sign_in_form(user)
- expect(current_path).to eq(invite_path(invite.raw_invite_token))
+ expect(current_path).to eq(invite_path(group_invite.raw_invite_token))
expect(page).to have_content(
'You have been invited by John Doe to join group Owned as Developer.'
)
@@ -45,7 +65,7 @@ describe 'Invites' do
end
it 'shows message user already a member' do
- visit invite_path(invite.raw_invite_token)
+ visit invite_path(group_invite.raw_invite_token)
expect(page).to have_content('However, you are already a member of this group.')
end
end
@@ -53,7 +73,7 @@ describe 'Invites' do
describe 'accepting the invitation' do
before do
sign_in(user)
- visit invite_path(invite.raw_invite_token)
+ visit invite_path(group_invite.raw_invite_token)
end
it 'grants access and redirects to group page' do
@@ -69,7 +89,7 @@ describe 'Invites' do
context 'when signed in' do
before do
sign_in(user)
- visit invite_path(invite.raw_invite_token)
+ visit invite_path(group_invite.raw_invite_token)
end
it 'declines application and redirects to dashboard' do
@@ -83,7 +103,7 @@ describe 'Invites' do
context 'when signed out' do
before do
- visit decline_invite_path(invite.raw_invite_token)
+ visit decline_invite_path(group_invite.raw_invite_token)
end
it 'declines application and redirects to sign in page' do
@@ -94,4 +114,72 @@ describe 'Invites' do
end
end
end
+
+ describe 'invite an user using their email address' do
+ let(:new_user) { build_stubbed(:user) }
+ let(:invite_email) { new_user.email }
+ let(:group_invite) { create(:group_member, :invited, group: group, invite_email: invite_email) }
+ let!(:project_invite) { create(:project_member, :invited, project: project, invite_email: invite_email) }
+
+ before do
+ stub_application_setting(send_user_confirmation_email: send_email_confirmation)
+ visit invite_path(group_invite.raw_invite_token)
+ end
+
+ context 'email confirmation disabled' do
+ let(:send_email_confirmation) { false }
+
+ it 'signs up and redirects to the dashboard page with all the projects/groups invitations automatically accepted' do
+ fill_in_sign_up_form(new_user)
+
+ expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_content(project.full_name)
+ visit group_path(group)
+ expect(page).to have_content(group.full_name)
+ end
+
+ context 'the user sign-up using a different email address' do
+ let(:invite_email) { build_stubbed(:user).email }
+
+ it 'signs up and redirects to the invitation page' do
+ fill_in_sign_up_form(new_user)
+
+ expect(current_path).to eq(invite_path(group_invite.raw_invite_token))
+ end
+ end
+ end
+
+ context 'email confirmation enabled' do
+ let(:send_email_confirmation) { true }
+
+ it 'signs up and redirects to root page with all the project/groups invitation automatically accepted' do
+ fill_in_sign_up_form(new_user)
+ confirm_email_and_sign_in(new_user)
+
+ expect(current_path).to eq(root_path)
+ expect(page).to have_content(project.full_name)
+ visit group_path(group)
+ expect(page).to have_content(group.full_name)
+ end
+
+ it "doesn't accept invitations until the user confirm his email" do
+ fill_in_sign_up_form(new_user)
+ sign_in(owner)
+
+ visit project_project_members_path(project)
+ expect(page).to have_content 'Invited'
+ end
+
+ context 'the user sign-up using a different email address' do
+ let(:invite_email) { build_stubbed(:user).email }
+
+ it 'signs up and redirects to the invitation page' do
+ fill_in_sign_up_form(new_user)
+ confirm_email_and_sign_in(new_user)
+
+ expect(current_path).to eq(invite_path(group_invite.raw_invite_token))
+ end
+ end
+ end
+ end
end
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index fe334b531f0..a8a627d8806 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -182,6 +182,7 @@ feature 'Gcp Cluster', :js do
it 'user sees a login page' do
expect(page).to have_css('.signin-with-google')
+ expect(page).to have_link('Google account')
end
end
diff --git a/spec/features/projects/commit/comments/user_adds_comment_spec.rb b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
new file mode 100644
index 00000000000..6397df086a7
--- /dev/null
+++ b/spec/features/projects/commit/comments/user_adds_comment_spec.rb
@@ -0,0 +1,170 @@
+require "spec_helper"
+
+describe "User adds a comment on a commit", :js do
+ include Spec::Support::Helpers::Features::NotesHelpers
+ include RepoHelpers
+
+ let(:comment_text) { "XML attached" }
+ let(:another_comment_text) { "SVG attached" }
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ project.add_developer(user)
+ end
+
+ context "inline view" do
+ before do
+ visit(project_commit_path(project, sample_commit.id))
+ end
+
+ it "adds a comment" do
+ page.within(".js-main-target-form") do
+ expect(page).not_to have_link("Cancel")
+
+ emoji = ":+1:"
+
+ fill_in("note[note]", with: "#{comment_text} #{emoji}")
+
+ # Check on `Preview` tab
+ click_link("Preview")
+
+ expect(find(".js-md-preview")).to have_content(comment_text).and have_css("gl-emoji")
+ expect(page).not_to have_css(".js-note-text")
+
+ # Check on the `Write` tab
+ click_link("Write")
+
+ expect(page).to have_field("note[note]", with: "#{comment_text} #{emoji}")
+
+ # Submit comment from the `Preview` tab to get rid of a separate `it` block
+ # which would specially tests if everything gets cleared from the note form.
+ click_link("Preview")
+ click_button("Comment")
+ end
+
+ wait_for_requests
+
+ page.within(".note") do
+ expect(page).to have_content(comment_text).and have_css("gl-emoji")
+ end
+
+ page.within(".js-main-target-form") do
+ expect(page).to have_field("note[note]", with: "").and have_no_css(".js-md-preview")
+ end
+ end
+
+ context "when commenting on diff" do
+ it "adds a comment" do
+ page.within(".diff-file:nth-of-type(1)") do
+ # Open a form for a comment and check UI elements are visible and acting as expecting.
+ click_diff_line(sample_commit.line_code)
+
+ expect(page).to have_css(".js-temp-notes-holder form.new-note")
+ .and have_css(".js-close-discussion-note-form", text: "Cancel")
+
+ # The `Cancel` button closes the current form. The page should not have any open forms after that.
+ find(".js-close-discussion-note-form").click
+
+ expect(page).not_to have_css("form.new_note")
+
+ # Try to open the same form twice. There should be only one form opened.
+ click_diff_line(sample_commit.line_code)
+ click_diff_line(sample_commit.line_code)
+
+ expect(page).to have_css("form.new-note", count: 1)
+
+ # Fill in a form.
+ page.within("form[data-line-code='#{sample_commit.line_code}']") do
+ fill_in("note[note]", with: "#{comment_text} :smile:")
+ end
+
+ # Open another form and check we have two forms now (because the first one is filled in).
+ click_diff_line(sample_commit.del_line_code)
+
+ expect(page).to have_field("note[note]", with: "#{comment_text} :smile:")
+ .and have_field("note[note]", with: "")
+
+ # Test Preview feature for both forms.
+ page.within("form[data-line-code='#{sample_commit.line_code}']") do
+ click_link("Preview")
+ end
+
+ page.within("form[data-line-code='#{sample_commit.del_line_code}']") do
+ fill_in("note[note]", with: another_comment_text)
+
+ click_link("Preview")
+ end
+
+ expect(page).to have_css(".js-md-preview", visible: true, count: 2)
+ .and have_content(comment_text)
+ .and have_content(another_comment_text)
+ .and have_xpath("//gl-emoji[@data-name='smile']")
+
+ # Test UI elements, then submit.
+ page.within("form[data-line-code='#{sample_commit.line_code}']") do
+ expect(find(".js-note-text", visible: false).text).to eq("")
+ expect(page).to have_css('.js-md-write-button')
+
+ click_button("Comment")
+ end
+
+ expect(page).to have_button("Reply...").and have_no_css("form.new_note")
+ end
+
+ # A comment should be added and visible.
+ page.within(".diff-file:nth-of-type(1) .note") do
+ expect(page).to have_content(comment_text).and have_xpath("//gl-emoji[@data-name='smile']")
+ end
+ end
+ end
+ end
+
+ context "side-by-side view" do
+ before do
+ visit(project_commit_path(project, sample_commit.id, view: "parallel"))
+ end
+
+ it "adds a comment" do
+ new_comment = "New comment"
+ old_comment = "Old comment"
+
+ # Left side.
+ click_parallel_diff_line(sample_commit.del_line_code)
+
+ page.within(".diff-file:nth-of-type(1) form[data-line-code='#{sample_commit.del_line_code}']") do
+ fill_in("note[note]", with: old_comment)
+ click_button("Comment")
+ end
+
+ page.within(".diff-file:nth-of-type(1) .notes_content.parallel.old") do
+ expect(page).to have_content(old_comment)
+ end
+
+ # Right side.
+ click_parallel_diff_line(sample_commit.line_code)
+
+ page.within(".diff-file:nth-of-type(1) form[data-line-code='#{sample_commit.line_code}']") do
+ fill_in("note[note]", with: new_comment)
+ click_button("Comment")
+ end
+
+ wait_for_requests
+
+ expect(all(".diff-file:nth-of-type(1) .notes_content.parallel.new")[1].text).to have_content(new_comment)
+ end
+ end
+
+ private
+
+ def click_diff_line(line)
+ find(".line_holder[id='#{line}'] td:nth-of-type(1)").hover
+ find(".line_holder[id='#{line}'] button").click
+ end
+
+ def click_parallel_diff_line(line)
+ find(".line_holder.parallel td[id='#{line}']").find(:xpath, 'preceding-sibling::*[1][self::td]').hover
+ find(".line_holder.parallel button[data-line-code='#{line}']").click
+ end
+end
diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
new file mode 100644
index 00000000000..a727cab4ac7
--- /dev/null
+++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
@@ -0,0 +1,37 @@
+require "spec_helper"
+
+describe "User deletes comments on a commit", :js do
+ include Spec::Support::Helpers::Features::NotesHelpers
+ include RepoHelpers
+
+ let(:comment_text) { "XML attached" }
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ project.add_developer(user)
+
+ visit(project_commit_path(project, sample_commit.id))
+
+ add_note(comment_text)
+ end
+
+ it "deletes comment" do
+ page.within(".note") do
+ expect(page).to have_content(comment_text)
+ end
+
+ page.within(".main-notes-list") do
+ note = find(".note")
+ note.hover
+
+ find(".more-actions").click
+ find(".more-actions .dropdown-menu li", match: :first)
+
+ accept_confirm { find(".js-note-delete").click }
+ end
+
+ expect(page).not_to have_css(".note")
+ end
+end
diff --git a/spec/features/projects/commit/comments/user_edits_comments_spec.rb b/spec/features/projects/commit/comments/user_edits_comments_spec.rb
new file mode 100644
index 00000000000..75bccd99f59
--- /dev/null
+++ b/spec/features/projects/commit/comments/user_edits_comments_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+
+describe "User edits a comment on a commit", :js do
+ include Spec::Support::Helpers::Features::NotesHelpers
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ project.add_developer(user)
+
+ visit(project_commit_path(project, sample_commit.id))
+
+ add_note("XML attached")
+ end
+
+ it "edits comment" do
+ NEW_COMMENT_TEXT = "+1 Awesome!".freeze
+
+ page.within(".main-notes-list") do
+ note = find(".note")
+ note.hover
+
+ note.find(".js-note-edit").click
+ end
+
+ page.find(".current-note-edit-form textarea")
+
+ page.within(".current-note-edit-form") do
+ fill_in("note[note]", with: NEW_COMMENT_TEXT)
+ click_button("Save comment")
+ end
+
+ wait_for_requests
+
+ page.within(".note") do
+ expect(page).to have_content(NEW_COMMENT_TEXT)
+ end
+ end
+end
diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb
deleted file mode 100644
index 5174f793367..00000000000
--- a/spec/features/projects/commit/user_comments_on_commit_spec.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-require "spec_helper"
-
-describe "User comments on commit", :js do
- include Spec::Support::Helpers::Features::NotesHelpers
- include RepoHelpers
-
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
-
- COMMENT_TEXT = "XML attached".freeze
-
- before do
- sign_in(user)
- project.add_developer(user)
-
- visit(project_commit_path(project, sample_commit.id))
- end
-
- context "when adding new comment" do
- it "adds comment" do
- EMOJI = ":+1:".freeze
-
- page.within(".js-main-target-form") do
- expect(page).not_to have_link("Cancel")
-
- fill_in("note[note]", with: "#{COMMENT_TEXT} #{EMOJI}")
-
- # Check on `Preview` tab
- click_link("Preview")
-
- expect(find(".js-md-preview")).to have_content(COMMENT_TEXT).and have_css("gl-emoji")
- expect(page).not_to have_css(".js-note-text")
-
- # Check on `Write` tab
- click_link("Write")
-
- expect(page).to have_field("note[note]", with: "#{COMMENT_TEXT} #{EMOJI}")
-
- # Submit comment from the `Preview` tab to get rid of a separate `it` block
- # which would specially tests if everything gets cleared from the note form.
- click_link("Preview")
- click_button("Comment")
- end
-
- wait_for_requests
-
- page.within(".note") do
- expect(page).to have_content(COMMENT_TEXT).and have_css("gl-emoji")
- end
-
- page.within(".js-main-target-form") do
- expect(page).to have_field("note[note]", with: "").and have_no_css(".js-md-preview")
- end
- end
- end
-
- context "when editing comment" do
- before do
- add_note(COMMENT_TEXT)
- end
-
- it "edits comment" do
- NEW_COMMENT_TEXT = "+1 Awesome!".freeze
-
- page.within(".main-notes-list") do
- note = find(".note")
- note.hover
-
- note.find(".js-note-edit").click
- end
-
- page.find(".current-note-edit-form textarea")
-
- page.within(".current-note-edit-form") do
- fill_in("note[note]", with: NEW_COMMENT_TEXT)
- click_button("Save comment")
- end
-
- wait_for_requests
-
- page.within(".note") do
- expect(page).to have_content(NEW_COMMENT_TEXT)
- end
- end
- end
-
- context "when deleting comment" do
- before do
- add_note(COMMENT_TEXT)
- end
-
- it "deletes comment" do
- page.within(".note") do
- expect(page).to have_content(COMMENT_TEXT)
- end
-
- page.within(".main-notes-list") do
- note = find(".note")
- note.hover
-
- find(".more-actions").click
- find(".more-actions .dropdown-menu li", match: :first)
-
- accept_confirm { find(".js-note-delete").click }
- end
-
- expect(page).not_to have_css(".note")
- end
- end
-end
diff --git a/spec/features/projects/merge_requests/user_creates_merge_request_spec.rb b/spec/features/projects/merge_requests/user_creates_merge_request_spec.rb
index f285c6c8783..1f21ef7b382 100644
--- a/spec/features/projects/merge_requests/user_creates_merge_request_spec.rb
+++ b/spec/features/projects/merge_requests/user_creates_merge_request_spec.rb
@@ -1,32 +1,84 @@
-require 'spec_helper'
+require "spec_helper"
-describe 'User creates a merge request', :js do
+describe "User creates a merge request", :js do
+ include ProjectForksHelper
+
+ let(:title) { "Some feature" }
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
project.add_master(user)
sign_in(user)
+ end
+ it "creates a merge request" do
visit(project_new_merge_request_path(project))
- end
- it 'creates a merge request' do
- find('.js-source-branch').click
- click_link('fix')
+ find(".js-source-branch").click
+ click_link("fix")
- find('.js-target-branch').click
- click_link('feature')
+ find(".js-target-branch").click
+ click_link("feature")
- click_button('Compare branches')
+ click_button("Compare branches")
- fill_in('merge_request_title', with: 'Wiki Feature')
- click_button('Submit merge request')
+ fill_in("Title", with: title)
+ click_button("Submit merge request")
- page.within('.merge-request') do
- expect(page).to have_content('Wiki Feature')
+ page.within(".merge-request") do
+ expect(page).to have_content(title)
end
+ end
+
+ context "to a forked project" do
+ let(:forked_project) { fork_project(project, user, namespace: user.namespace, repository: true) }
+
+ it "creates a merge request" do
+ visit(project_new_merge_request_path(forked_project))
+
+ expect(page).to have_content("Source branch").and have_content("Target branch")
+ expect(find("#merge_request_target_project_id", visible: false).value).to eq(project.id.to_s)
+
+ click_button("Compare branches and continue")
+
+ expect(page).to have_content("You must select source and target branch")
+
+ first(".js-source-project").click
+ first(".dropdown-source-project a", text: forked_project.full_path)
+
+ first(".js-target-project").click
+ first(".dropdown-target-project a", text: project.full_path)
+
+ first(".js-source-branch").click
- wait_for_requests
+ wait_for_requests
+
+ source_branch = "fix"
+
+ first(".js-source-branch-dropdown .dropdown-content a", text: source_branch).click
+
+ click_button("Compare branches and continue")
+
+ expect(page).to have_css("h3.page-title", text: "New Merge Request")
+
+ page.within("form#new_merge_request") do
+ fill_in("Title", with: title)
+ end
+
+ click_button("Assignee")
+
+ expect(find(".js-assignee-search")["data-project-id"]).to eq(project.id.to_s)
+
+ page.within(".dropdown-menu-user") do
+ expect(page).to have_content("Unassigned")
+ .and have_content(user.name)
+ .and have_content(project.users.first.name)
+ end
+
+ click_button("Submit merge request")
+
+ expect(page).to have_content(title).and have_content("Request to merge #{user.namespace.name}:#{source_branch} into master")
+ end
end
end
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index e875a88a52b..cfdae246c09 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -75,6 +75,29 @@ describe "Projects > Settings > Pipelines settings" do
expect(project.auto_devops).not_to be_enabled
expect(project.auto_devops.domain).to eq('test.com')
end
+
+ context 'when there is a cluster with ingress and external_ip' do
+ before do
+ cluster = create(:cluster, projects: [project])
+ cluster.create_application_ingress!(external_ip: '192.168.1.100')
+ end
+
+ it 'shows the help text with the nip.io domain as an alternative to custom domain' do
+ visit project_settings_ci_cd_path(project)
+ expect(page).to have_content('192.168.1.100.nip.io can be used as an alternative to a custom domain')
+ end
+ end
+
+ context 'when there is no ingress' do
+ before do
+ create(:cluster, projects: [project])
+ end
+
+ it 'alternative to custom domain is not shown' do
+ visit project_settings_ci_cd_path(project)
+ expect(page).not_to have_content('can be used as an alternative to a custom domain')
+ end
+ end
end
end
end
diff --git a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
index ab9420fc38f..2c67cec6b67 100644
--- a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'User deletes wiki page' do
+feature 'User deletes wiki page', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki) }
@@ -13,6 +13,7 @@ feature 'User deletes wiki page' do
it 'deletes a page' do
click_on('Edit')
click_on('Delete')
+ find('.js-modal-primary-action').click
expect(page).to have_content('Page was successfully deleted')
end