Commit 98278abd authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'blackst0ne-replace-spinach-project-issues-issues.feature' into 'master'

Replace the `project/issues/issues.feature` spinach test with an rspec analog

See merge request gitlab-org/gitlab-ce!17950
parents 95b3bf26 dc4ae317
---
title: Replace the spinach test with an rspec analog
merge_request: 17950
author: blackst0ne
type: other
@project_issues
Feature: Project Issues
Background:
Given I sign in as a user
And I own project "Shop"
And project "Shop" have "Release 0.4" open issue
And project "Shop" have "Tweet control" open issue
And project "Shop" have "Release 0.3" closed issue
And I visit project "Shop" issues page
Scenario: I should see open issues
Given I should see "Release 0.4" in issues
And I should not see "Release 0.3" in issues
@javascript
Scenario: I should see closed issues
Given I click link "Closed"
Then I should see "Release 0.3" in issues
And I should not see "Release 0.4" in issues
@javascript
Scenario: I should see all issues
Given I click link "All"
Then I should see "Release 0.3" in issues
And I should see "Release 0.4" in issues
Scenario: I visit issue page
Given I click link "Release 0.4"
Then I should see issue "Release 0.4"
Scenario: I submit new unassigned issue
Given I click link "New Issue"
And I submit new issue "500 error on profile"
Then I should see issue "500 error on profile"
@javascript
Scenario: I submit new unassigned issue with labels
Given project "Shop" has labels: "bug", "feature", "enhancement"
And I click link "New Issue"
And I submit new issue "500 error on profile" with label 'bug'
Then I should see issue "500 error on profile"
And I should see label 'bug' with issue
@javascript
Scenario: I comment issue
Given I visit issue page "Release 0.4"
And I leave a comment like "XML attached"
Then I should see comment "XML attached"
And I should see an error alert section within the comment form
@javascript
Scenario: Visiting Issues after being sorted the list
Given I visit project "Shop" issues page
And I sort the list by "Last updated"
And I visit my project's home page
And I visit project "Shop" issues page
Then The list should be sorted by "Last updated"
@javascript
Scenario: Visiting Merge Requests after being sorted the list
Given project "Shop" has a "Bugfix MR" merge request open
And I visit project "Shop" issues page
And I sort the list by "Last updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Last updated"
@javascript
Scenario: Visiting Merge Requests from a differente Project after sorting
Given project "Shop" has a "Bugfix MR" merge request open
And I visit project "Shop" merge requests page
And I sort the list by "Last updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Last updated"
@javascript
Scenario: Sort issues by upvotes/downvotes
Given project "Shop" have "Bugfix" open issue
And issue "Release 0.4" have 2 upvotes and 1 downvote
And issue "Tweet control" have 1 upvote and 2 downvotes
And I sort the list by "Popularity"
Then The list should be sorted by "Popularity"
# Markdown
@javascript
Scenario: Headers inside the description should have ids generated for them.
Given I visit issue page "Release 0.4"
Then Header "Description header" should have correct id and link
@javascript
Scenario: Headers inside comments should not have ids generated for them.
Given I visit issue page "Release 0.4"
And I leave a comment with a header containing "Comment with a header"
Then The comment with the header should not have an ID
@javascript
Scenario: Blocks inside comments should not build relative links
Given I visit issue page "Release 0.4"
And I leave a comment with code block
Then The code block should be unchanged
Scenario: Issues on empty project
Given empty project "Empty Project"
And I have an ssh key
When I visit empty project page
And I see empty project details with ssh clone info
When I visit empty project's issues page
Given I click link "New Issue"
And I submit new issue "500 error on profile"
Then I should see issue "500 error on profile"
Scenario: Clickable labels
Given issue 'Release 0.4' has label 'bug'
And I visit project "Shop" issues page
When I click label 'bug'
And I should see "Release 0.4" in issues
And I should not see "Tweet control" in issues
@javascript
Scenario: Issue notes should be editable with +1
Given project "Shop" have "Release 0.4" open issue
When I visit issue page "Release 0.4"
And I leave a comment with a header containing "Comment with a header"
Then The comment with the header should not have an ID
And I edit the last comment with a +1
Then I should see +1 in the description
# Issue description preview
@javascript
Scenario: I can't preview without text
Given I click link "New Issue"
And I haven't written any description text
Then The Markdown preview tab should say there is nothing to do
@javascript
Scenario: I can preview with text
Given I click link "New Issue"
And I write a description like ":+1: Nice"
Then The Markdown preview tab should display rendered Markdown
@javascript
Scenario: I preview an issue description
Given I click link "New Issue"
And I preview a description text like "Bug fixed :smile:"
Then I should see the Markdown preview
And I should not see the Markdown text field
@javascript
Scenario: I can edit after preview
Given I click link "New Issue"
And I preview a description text like "Bug fixed :smile:"
Then I should see the Markdown write tab
@javascript
Scenario: I can preview when editing an existing issue
Given I click link "Release 0.4"
And I click link "Edit" for the issue
And I preview a description text like "Bug fixed :smile:"
Then I should see the Markdown write tab
@javascript
Scenario: I can unsubscribe from issue
Given project "Shop" have "Release 0.4" open issue
When I visit issue page "Release 0.4"
Then I should see that I am subscribed
When I click the subscription toggle
Then I should see that I am unsubscribed
@javascript
Scenario: I submit new unassigned issue as guest
Given public project "Community"
When I visit project "Community" page
And I visit project "Community" issues page
And I click link "New Issue"
And I should not see assignee field
And I should not see milestone field
And I should not see labels field
And I submit new issue "500 error on profile"
Then I should see issue "500 error on profile"
......@@ -39,4 +39,5 @@ Feature: Project Issues Milestones
Scenario: Headers inside the description should have ids generated for them.
Given I click link "v2.2"
# PLEASE USE the `have_header_with_correct_id_and_link(level, text, id, parent)` matcher on migrating this spec to rspec.
Then Header "Description header" should have correct id and link
......@@ -7,36 +7,14 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
include SharedMarkdown
include SharedUser
step 'I should see "Release 0.4" in issues' do
expect(page).to have_content "Release 0.4"
end
step 'I should not see "Release 0.3" in issues' do
expect(page).not_to have_content "Release 0.3"
end
step 'I should not see "Tweet control" in issues' do
expect(page).not_to have_content "Tweet control"
end
step 'I should see that I am subscribed' do
wait_for_requests
expect(find('.js-issuable-subscribe-button')).to have_css 'button.is-checked'
end
step 'I should see that I am unsubscribed' do
wait_for_requests
expect(find('.js-issuable-subscribe-button')).to have_css 'button:not(.is-checked)'
end
step 'I click link "Closed"' do
find('.issues-state-filters [data-state="closed"] span', text: 'Closed').click
end
step 'I click the subscription toggle' do
find('.js-issuable-subscribe-button button').click
end
step 'I should see "Release 0.3" in issues' do
expect(page).to have_content "Release 0.3"
end
......@@ -51,24 +29,10 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
expect(find('.issues-state-filters > .active')).to have_content 'All'
end
step 'I click link "Release 0.4"' do
click_link "Release 0.4"
end
step 'I should see issue "Release 0.4"' do
expect(page).to have_content "Release 0.4"
end
step 'I should see issue "Tweet control"' do
expect(page).to have_content "Tweet control"
end
step 'I click link "New issue"' do
page.within '#content-body' do
page.has_link?('New Issue') ? click_link('New Issue') : click_link('New issue')
end
end
step 'I click "author" dropdown' do
page.find('.js-author-search').click
sleep 1
......@@ -81,18 +45,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
expect(users[1].text).to eq "#{current_user.name} #{current_user.to_reference}"
end
step 'I submit new issue "500 error on profile"' do
fill_in "issue_title", with: "500 error on profile"
click_button "Submit issue"
end
step 'I submit new issue "500 error on profile" with label \'bug\'' do
fill_in "issue_title", with: "500 error on profile"
click_button "Label"
click_link "bug"
click_button "Submit issue"
end
step 'I click link "500 error on profile"' do
click_link "500 error on profile"
end
......@@ -103,13 +55,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
step 'I should see issue "500 error on profile"' do
issue = Issue.find_by(title: "500 error on profile")
expect(page).to have_content issue.title
expect(page).to have_content issue.author_name
expect(page).to have_content issue.project.name
end
step 'I fill in issue search with "Re"' do
filter_issue "Re"
end
......@@ -163,49 +108,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
expect(find(issues_assignee_selector)).to have_content(assignee_name)
end
step 'project "Shop" have "Release 0.4" open issue' do
create(:issue,
title: "Release 0.4",
project: project,
author: project.users.first,
description: "# Description header"
)
wait_for_requests
end
step 'project "Shop" have "Tweet control" open issue' do
create(:issue,
title: "Tweet control",
project: project,
author: project.users.first)
end
step 'project "Shop" have "Bugfix" open issue' do
create(:issue,
title: "Bugfix",
project: project,
author: project.users.first)
end
step 'project "Shop" have "Release 0.3" closed issue' do
create(:closed_issue,
title: "Release 0.3",
project: project,
author: project.users.first)
end
step 'issue "Release 0.4" have 2 upvotes and 1 downvote' do
awardable = Issue.find_by(title: 'Release 0.4')
create_list(:award_emoji, 2, awardable: awardable)
create(:award_emoji, :downvote, awardable: awardable)
end
step 'issue "Tweet control" have 1 upvote and 2 downvotes' do
awardable = Issue.find_by(title: 'Tweet control')
create(:award_emoji, :upvote, awardable: awardable)
create_list(:award_emoji, 2, awardable: awardable, name: 'thumbsdown')
end
step 'The list should be sorted by "Least popular"' do
page.within '.issues-list' do
page.within 'li.issue:nth-child(1)' do
......@@ -225,69 +127,16 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
step 'The list should be sorted by "Popularity"' do
page.within '.issues-list' do
page.within 'li.issue:nth-child(1)' do
expect(page).to have_content 'Release 0.4'
expect(page).to have_content '2 1'
end
page.within 'li.issue:nth-child(2)' do
expect(page).to have_content 'Tweet control'
expect(page).to have_content '1 2'
end
page.within 'li.issue:nth-child(3)' do
expect(page).to have_content 'Bugfix'
expect(page).not_to have_content '0 0'
end
end
end
step 'empty project "Empty Project"' do
create :project_empty_repo, name: 'Empty Project', namespace: @user.namespace
end
When 'I visit empty project page' do
project = Project.find_by(name: 'Empty Project')
visit project_path(project)
end
step 'I see empty project details with ssh clone info' do
project = Project.find_by(name: 'Empty Project')
page.all(:css, '.git-empty .clone').each do |element|
expect(element.text).to include(project.url_to_repo)
end
end
When "I visit project \"Community\" issues page" do
project = Project.find_by(name: 'Community')
visit project_issues_path(project)
end
When "I visit empty project's issues page" do
project = Project.find_by(name: 'Empty Project')
visit project_issues_path(project)
end
step 'I leave a comment with code block' do
page.within(".js-main-target-form") do
fill_in "note[note]", with: "```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```"
click_button "Comment"
sleep 0.05
end
end
step 'I should see an error alert section within the comment form' do
page.within(".js-main-target-form") do
find(".error-alert")
end
end
step 'The code block should be unchanged' do
expect(page).to have_content("```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```")
end
step 'project \'Shop\' has issue \'Bugfix1\' with description: \'Description for issue1\'' do
create(:issue, title: 'Bugfix1', description: 'Description for issue1', project: project)
end
......@@ -320,36 +169,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
expect(page).not_to have_content 'Bugfix1'
end
step 'issue \'Release 0.4\' has label \'bug\'' do
label = project.labels.create!(name: 'bug', color: '#990000')
issue = Issue.find_by!(title: 'Release 0.4')
issue.labels << label
end
step 'I click label \'bug\'' do
page.within ".issues-list" do
click_link 'bug'
end
end
step 'I should not see labels field' do
page.within '.issue-form' do
expect(page).not_to have_content("Labels")
end
end
step 'I should not see milestone field' do
page.within '.issue-form' do
expect(page).not_to have_content("Milestone")
end
end
step 'I should not see assignee field' do
page.within '.issue-form' do
expect(page).not_to have_content("Assign to")
end
end
def filter_issue(text)
fill_in 'issuable_search', with: text
end
......
......@@ -105,17 +105,6 @@ module SharedIssuable
edit_issuable
end
step 'I click link "Edit" for the issue' do
edit_issuable
end
step 'I sort the list by "Last updated"' do
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link "Last updated"
end
end
step 'I sort the list by "Least popular"' do
find('button.dropdown-toggle').click
......@@ -124,18 +113,6 @@ module SharedIssuable
end
end
step 'I sort the list by "Popularity"' do
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link 'Popularity'
end
end
step 'The list should be sorted by "Last updated"' do
expect(find('.issues-filters')).to have_content('Last updated')
end
step 'I click link "Next" in the sidebar' do
page.within '.issuable-sidebar' do
click_link 'Next'
......
......@@ -18,43 +18,6 @@ module SharedMarkdown
expect(find('.gfm-form .js-md-preview')).not_to be_visible
end
step 'The Markdown preview tab should say there is nothing to do' do
page.within('.gfm-form') do
find('.js-md-preview-button').click
expect(find('.js-md-preview')).to have_content('Nothing to preview.')
end
end
step 'I should not see the Markdown text field' do
expect(find('.gfm-form textarea')).not_to be_visible
end
step 'I should see the Markdown write tab' do
expect(first('.gfm-form')).to have_link('Write', visible: true)
end
step 'I should see the Markdown preview' do
expect(find('.gfm-form')).to have_css('.js-md-preview', visible: true)
end
step 'The Markdown preview tab should display rendered Markdown' do
page.within('.gfm-form') do
find('.js-md-preview-button').click
expect(find('.js-md-preview')).to have_css('gl-emoji', visible: true)
end
end
step 'I write a description like ":+1: Nice"' do
find('.gfm-form').fill_in 'Description', with: ':+1: Nice'
end
step 'I preview a description text like "Bug fixed :smile:"' do
page.within(first('.gfm-form')) do
fill_in 'Description', with: 'Bug fixed :smile:'
click_link 'Preview'
end
end
step 'I haven\'t written any description text' do
find('.gfm-form').fill_in 'Description', with: ''
end
......
......@@ -114,34 +114,12 @@ module SharedNote
end
end
step 'I should see comment "XML attached"' do
page.within(".note") do
expect(page).to have_content("XML attached")
end
end
step 'I should see no notes at all' do
expect(page).not_to have_css('.note')
end
# Markdown
step 'I leave a comment with a header containing "Comment with a header"' do
page.within(".js-main-target-form") do
fill_in "note[note]", with: "# Comment with a header"
click_button "Comment"
end
wait_for_requests
end
step 'The comment with the header should not have an ID' do
page.within(".note-body > .note-text") do
expect(page).to have_content("Comment with a header")
expect(page).not_to have_css("#comment-with-a-header")
end
end
step 'I edit the last comment with a +1' do
page.within(".main-notes-list") do
note = find('.note')
......
......@@ -96,10 +96,6 @@ module SharedPaths
visit assigned_issues_dashboard_path
end
step 'I visit dashboard merge requests page' do
visit assigned_mrs_dashboard_path
end
step 'I visit dashboard search page' do
visit search_path
end
......@@ -200,10 +196,6 @@ module SharedPaths
# Generic Project
# ----------------------------------------
step "I visit my project's home page" do
visit project_path(@project)
end
step "I visit my project's settings page" do
visit edit_project_path(@project)
end
......@@ -339,10 +331,6 @@ module SharedPaths
visit project_commit_path(@project, sample_commit.id)
end
step 'I visit project "Shop" issues page' do
visit project_issues_path(project)
end
step 'I visit issue page "Release 0.4"' do
issue = Issue.find_by(title: "Release 0.4")
visit project_issue_path(issue.project, issue)
......@@ -394,10 +382,6 @@ module SharedPaths
wait_for_requests
end
step 'I visit project "Shop" merge requests page' do
visit project_merge_requests_path(project)
end
step 'I visit forked project "Shop" merge requests page' do
visit project_merge_requests_path(project)
end
......@@ -418,11 +402,6 @@ module SharedPaths
# Visibility Projects
# ----------------------------------------
step 'I visit project "Community" page' do
project = Project.find_by(name: "Community")
visit project_path(project)
end
step 'I visit project "Community" source page' do
project = Project.find_by(name: 'Community')
visit project_tree_path(project, root_ref)
......@@ -442,11 +421,6 @@ module SharedPaths
# Empty Projects
# ----------------------------------------
step "I visit empty project page" do
project = Project.find_by(name: "Empty Public Project")
visit project_path(project)
end
step "I should not see command line instructions" do
expect(page).not_to have_css('.empty_wrapper')
end
......
......@@ -236,10 +236,6 @@ module SharedProject
@project.update(public_builds: false)
end
step 'project "Shop" has a "Bugfix MR" merge request open' do
create(:merge_request, title: "Bugfix MR", target_project: project, source_project: project, author: project.users.first)
end
def user_owns_project(user_name:, project_name:, visibility: :private)
user = user_exists(user_name, username: user_name.gsub(/\s/, '').underscore)
project = Project.find_by(name: project_name)
......
......@@ -19,10 +19,6 @@ module SharedUser
User.find_by(name: name) || create(:user, { name: name, admin: false }.merge(options))
end
step 'I have an ssh key' do
create(:personal_key, user: @user)
end
step 'I have no ssh keys' do
@user.keys.delete_all
end
......
require 'spec_helper'
feature 'Dashboard Issues filtering', :js do
include SortingHelper
include Spec::Support::Helpers::Features::SortingHelpers
let(:user) { create(:user) }
let(:project) { create(:project) }
......@@ -90,14 +90,14 @@ feature 'Dashboard Issues filtering', :js do
context 'sorting' do
it 'shows sorted issues' do
sorting_by('Created date')
sort_by('Created date')
visit_issues
expect(find('.issues-filters')).to have_content('Created date')
end
it 'keeps sorting issues after visiting Projects Issues page' do
sorting_by('Created date')
sort_by('Created date')
visit project_issues_path(project)
expect(find('.issues-filters')).to have_content('Created date')
......
require 'spec_helper'
feature 'Dashboard Merge Requests' do
include Spec::Support::Helpers::Features::SortingHelpers
include FilterItemSelectHelper
include SortingHelper
include ProjectForksHelper
let(:current_user) { create :user }
......@@ -115,7 +115,7 @@ feature 'Dashboard Merge Requests' do
end
it 'shows sorted merge requests' do
sorting_by('Created date')
sort_by('Created date')
visit merge_requests_dashboard_path(assignee_id: current_user.id)
......@@ -123,7 +123,7 @@ feature 'Dashboard Merge Requests' do
end
it 'keeps sorting merge requests after visiting Projects MR page' do
sorting_by('Created date')
sort_by('Created date')
visit project_merge_requests_path(project)
......
require 'rails_helper'
feature 'Issues > User uses quick actions', :js do
include QuickActionsHelpers
include Spec::Support::Helpers::Features::NotesHelpers
it_behaves_like 'issuable record that supports quick actions in its description and notes', :issue do
let(:issuable) { create(:issue, project: project) }
......@@ -36,7 +36,7 @@ feature 'Issues > User uses quick actions', :js do
context 'when the current user can update the due date' do
it 'does not create a note, and sets the due date accordingly' do
write_note("/due 2016-08-28")
add_note("/due 2016-08-28")
expect(page).not_to have_content '/due 2016-08-28'
expect(page).to have_content 'Commands applied'
......@@ -57,7 +57,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and sets the due date accordingly' do
write_note("/due 2016-08-28")
add_note("/due 2016-08-28")
expect(page).not_to have_content 'Commands applied'
......@@ -75,7 +75,7 @@ feature 'Issues > User uses quick actions', :js do
it 'does not create a note, and removes the due date accordingly' do
expect(issue.due_date).to eq Date.new(2016, 8, 28)
write_note("/remove_due_date")
add_note("/remove_due_date")
expect(page).not_to have_content '/remove_due_date'
expect(page).to have_content 'Commands applied'
......@@ -96,7 +96,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and sets the due date accordingly' do
write_note("/remove_due_date")
add_note("/remove_due_date")
expect(page).not_to have_content 'Commands applied'
......@@ -111,7 +111,7 @@ feature 'Issues > User uses quick actions', :js do
let(:issue) { create(:issue, project: project) }
it 'does not recognize the command nor create a note' do
write_note("/wip")
add_note("/wip")
expect(page).not_to have_content '/wip'
end
......@@ -123,7 +123,7 @@ feature 'Issues > User uses quick actions', :js do
context 'when the current user can update issues' do
it 'does not create a note, and marks the issue as a duplicate' do
write_note("/duplicate ##{original_issue.to_reference}")
add_note("/duplicate ##{original_issue.to_reference}")
expect(page).not_to have_content "/duplicate #{original_issue.to_reference}"
expect(page).to have_content 'Commands applied'
......@@ -143,7 +143,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not create a note, and does not mark the issue as a duplicate' do
write_note("/duplicate ##{original_issue.to_reference}")
add_note("/duplicate ##{original_issue.to_reference}")
expect(page).not_to have_content 'Commands applied'
expect(page).not_to have_content "marked this issue as a duplicate of #{original_issue.to_reference}"
......@@ -166,7 +166,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'moves the issue' do
write_note("/move #{target_project.full_path}")
add_note("/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
......@@ -186,7 +186,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not move the issue' do
write_note("/move #{project_unauthorized.full_path}")
add_note("/move #{project_unauthorized.full_path}")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
......@@ -200,7 +200,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'does not move the issue' do
write_note("/move not/valid")
add_note("/move not/valid")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
......@@ -223,7 +223,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'applies the commands to both issues and moves the issue' do
write_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}")
add_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
......@@ -242,7 +242,7 @@ feature 'Issues > User uses quick actions', :js do
end
it 'moves the issue and applies the commands to both issues' do
write_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"")
add_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
......
require 'rails_helper'
describe 'Merge request > User uses quick actions', :js do
include QuickActionsHelpers
include Spec::Support::Helpers::Features::NotesHelpers
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
......@@ -33,7 +33,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'toggling the WIP prefix in the title from note' do
context 'when the current user can toggle the WIP prefix' do
it 'adds the WIP: prefix to the title' do
write_note("/wip")
add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).to have_content 'Commands applied'
......@@ -44,7 +44,7 @@ describe 'Merge request > User uses quick actions', :js do
it 'removes the WIP: prefix from the title' do
merge_request.title = merge_request.wip_title
merge_request.save
write_note("/wip")
add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).to have_content 'Commands applied'
......@@ -62,7 +62,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not change the WIP prefix' do
write_note("/wip")
add_note("/wip")
expect(page).not_to have_content '/wip'
expect(page).not_to have_content 'Commands applied'
......@@ -75,7 +75,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'merging the MR from the note' do
context 'when the current user can merge the MR' do
it 'merges the MR' do
write_note("/merge")
add_note("/merge")
expect(page).to have_content 'Commands applied'
......@@ -90,7 +90,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not merge the MR' do
write_note("/merge")
add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
......@@ -107,7 +107,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not merge the MR' do
write_note("/merge")
add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
......@@ -118,7 +118,7 @@ describe 'Merge request > User uses quick actions', :js do
describe 'adding a due date from note' do
it 'does not recognize the command nor create a note' do
write_note('/due 2016-08-28')
add_note('/due 2016-08-28')
expect(page).not_to have_content '/due 2016-08-28'
end
......@@ -162,7 +162,7 @@ describe 'Merge request > User uses quick actions', :js do
describe '/target_branch command from note' do
context 'when the current user can change target branch' do
it 'changes target branch from a note' do
write_note("message start \n/target_branch merge-test\n message end.")
add_note("message start \n/target_branch merge-test\n message end.")
wait_for_requests
expect(page).not_to have_content('/target_branch')
......@@ -173,7 +173,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not fail when target branch does not exists' do
write_note('/target_branch totally_not_existing_branch')
add_note('/target_branch totally_not_existing_branch')
expect(page).not_to have_content('/target_branch')
......@@ -190,7 +190,7 @@ describe 'Merge request > User uses quick actions', :js do
end
it 'does not change target branch' do
write_note('/target_branch merge-test')
add_note('/target_branch merge-test')
expect(page).not_to have_content '/target_branch merge-test'
......
require "spec_helper"
describe "User comments on issue", :js do
include Spec::Support::Helpers::Features::NotesHelpers
let(:project) { create(:project_empty_repo, :public) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
before do
project.add_guest(user)
sign_in(user)
visit(project_issue_path(project, issue))
end
context "when adding comments" do
it "adds comment" do
content = "XML attached"
target_form = ".js-main-target-form"
add_note(content)
page.within(".note") do
expect(page).to have_content(content)
end
page.within(target_form) do
find(".error-alert", visible: false)
end
end
it "adds comment with code block" do
comment = "```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```"
add_note(comment)
expect(page).to have_content(comment)
end
end
context "when editing comments" do
it "edits comment" do
add_note("# Comment with a header")
page.within(".note-body > .note-text") do
expect(page).to have_content("Comment with a header").and have_no_css("#comment-with-a-header")
end
page.within(".main-notes-list") do
note = find(".note")
note.hover
note.find(".js-note-edit").click
end
expect(page).to have_css(".current-note-edit-form textarea")
comment = "+1 Awesome!"
page.within(".current-note-edit-form") do
fill_in("note[note]", with: comment)
click_button("Save comment")
end
wait_for_requests
page.within(".note") do
expect(page).to have_content(comment)
end
end
end
end
require "spec_helper"
describe "User creates issue" do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
context "when signed in as guest" do
before do
project.add_guest(user)
sign_in(user)
visit(new_project_issue_path(project))
end
it "creates issue" do
page.within(".issue-form") do
expect(page).to have_no_content("Assign to")
.and have_no_content("Labels")
.and have_no_content("Milestone")
end
issue_title = "500 error on profile"
fill_in("Title", with: issue_title)
click_button("Submit issue")
expect(page).to have_content(issue_title)
.and have_content(user.name)
.and have_content(project.name)
end
end
context "when signed in as developer", :js do
before do
project.add_developer(user)
sign_in(user)
visit(new_project_issue_path(project))
end
context "when previewing" do
it "previews content" do
form = first(".gfm-form")
textarea = first(".gfm-form textarea")
page.within(form) do
click_link("Preview")
preview = find(".js-md-preview") # this element is findable only when the "Preview" link is clicked.
expect(preview).to have_content("Nothing to preview.")
click_link("Write")
fill_in("Description", with: "Bug fixed :smile:")
click_link("Preview")
expect(preview).to have_css("gl-emoji")
expect(textarea).not_to be_visible
end
end
end
context "with labels" do
LABEL_TITLES = %w(bug feature enhancement).freeze
before do
LABEL_TITLES.each do |title|
create(:label, project: project, title: title)
end
end
it "creates issue" do
issue_title = "500 error on profile"
fill_in("Title", with: issue_title)
click_button("Label")
click_link(LABEL_TITLES.first)
click_button("Submit issue")
expect(page).to have_content(issue_title)
.and have_content(user.name)
.and have_content(project.name)
.and have_content(LABEL_TITLES.first)
end
end
end
end
require "spec_helper"
describe "User edits issue", :js do
set(:project) { create(:project_empty_repo, :public) }
set(:user) { create(:user) }
set(:issue) { create(:issue, project: project, author: user) }
before do
project.add_developer(user)
sign_in(user)
visit(edit_project_issue_path(project, issue))
end
it "previews content" do
form = first(".gfm-form")
page.within(form) do
fill_in("Description", with: "Bug fixed :smile:")
click_link("Preview")
end
expect(form).to have_link("Write")
end
end
require "spec_helper"
describe "User sorts issues" do
set(:project) { create(:project_empty_repo, :public) }
set(:issue1) { create(:issue, project: project) }
set(:issue2) { create(:issue, project: project) }
set(:issue3) { create(:issue, project: project) }
before do
create_list(:award_emoji, 2, :upvote, awardable: issue1)
create_list(:award_emoji, 2, :downvote, awardable: issue2)
create(:award_emoji, :downvote, awardable: issue1)
create(:award_emoji, :upvote, awardable: issue2)
visit(project_issues_path(project))
end
it "sorts by popularity" do
find("button.dropdown-toggle").click
page.within(".content ul.dropdown-menu.dropdown-menu-align-right li") do
click_link("Popularity")
end
page.within(".issues-list") do
page.within("li.issue:nth-child(1)") do
expect(page).to have_content(issue1.title)
expect(page).to have_content("2 1")
end
page.within("li.issue:nth-child(2)") do
expect(page).to have_content(issue2.title)
expect(page).to have_content("1 2")
end
page.within("li.issue:nth-child(3)") do
expect(page).to have_content(issue3.title)
expect(page).not_to have_content("0 0")
end
end
end
end
require "spec_helper"
describe "User toggles subscription", :js do
set(:project) { create(:project_empty_repo, :public) }
set(:user) { create(:user) }
set(:issue) { create(:issue, project: project, author: user) }
before do
project.add_developer(user)
sign_in(user)
visit(project_issue_path(project, issue))
end
it "unsibscribes from issue" do
subscription_button = find(".js-issuable-subscribe-button")
# Check we're subscribed.
expect(subscription_button).to have_css("button.is-checked")
# Toggle subscription.
find(".js-issuable-subscribe-button button").click
wait_for_requests
# Check we're unsubscribed.
expect(subscription_button).to have_css("button:not(.is-checked)")
end
end
require "spec_helper"
describe "User views issue" do
set(:project) { create(:project_empty_repo, :public) }
set(:user) { create(:user) }
set(:issue) { create(:issue, project: project, description: "# Description header", author: user) }
before do
project.add_guest(user)
sign_in(user)
visit(project_issue_path(project, issue))
end
it { expect(page).to have_header_with_correct_id_and_link(1, "Description header", "description-header") }
end
require 'spec_helper'
require "spec_helper"
describe 'User views issues' do
describe "User views issues" do
let!(:closed_issue) { create(:closed_issue, project: project) }
let!(:open_issue1) { create(:issue, project: project) }
let!(:open_issue2) { create(:issue, project: project) }
set(:user) { create(:user) }
shared_examples_for 'shows issues' do
it 'shows issues' do
expect(page).to have_content(project.name)
.and have_content(issue1.title)
.and have_content(issue2.title)
.and have_no_selector('.js-new-board-list')
shared_examples "opens issue from list" do
it "opens issue" do
click_link(issue.title)
expect(page).to have_content(issue.title)
end
end
context 'when project is public' do
set(:project) { create(:project_empty_repo, :public) }
set(:issue1) { create(:issue, project: project) }
set(:issue2) { create(:issue, project: project) }
shared_examples "open issues" do
context "open issues" do
let(:label) { create(:label, project: project, title: "bug") }
context 'when signed in' do
before do
project.add_developer(user)
sign_in(user)
open_issue1.labels << label
visit(project_issues_path(project, state: :opened))
end
visit(project_issues_path(project))
it "shows open issues" do
expect(page).to have_content(project.name)
.and have_content(open_issue1.title)
.and have_content(open_issue2.title)
.and have_no_content(closed_issue.title)
.and have_no_selector(".js-new-board-list")
end
include_examples 'shows issues'
it "opens issues by label" do
page.within(".issues-list") do
click_link(label.title)
end
expect(page).to have_content(open_issue1.title)
.and have_no_content(open_issue2.title)
.and have_no_content(closed_issue.title)
end
include_examples "opens issue from list" do
let(:issue) { open_issue1 }
end
end
end
context 'when not signed in' do
shared_examples "closed issues" do
context "closed issues" do
before do
visit(project_issues_path(project))
visit(project_issues_path(project, state: :closed))
end
it "shows closed issues" do
expect(page).to have_content(project.name)
.and have_content(closed_issue.title)
.and have_no_content(open_issue1.title)
.and have_no_content(open_issue2.title)
.and have_no_selector(".js-new-board-list")
end
include_examples 'shows issues'
include_examples "opens issue from list" do
let(:issue) { closed_issue }
end
end
end
context 'when project is internal' do
set(:project) { create(:project_empty_repo, :internal) }
set(:issue1) { create(:issue, project: project) }
set(:issue2) { create(:issue, project: project) }
context 'when signed in' do
shared_examples "all issues" do
context "all issues" do
before do
project.add_developer(user)
sign_in(user)
visit(project_issues_path(project, state: :all))
end
visit(project_issues_path(project))
it "shows all issues" do
expect(page).to have_content(project.name)
.and have_content(closed_issue.title)
.and have_content(open_issue1.title)
.and have_content(open_issue2.title)
.and have_no_selector(".js-new-board-list")
end
include_examples 'shows issues'
include_examples "opens issue from list" do
let(:issue) { closed_issue }
end
end
end
%w[internal public].each do |visibility|
shared_examples "#{visibility} project" do
context "when project is #{visibility}" do
let(:project) { create(:project_empty_repo, :"#{visibility}") }
include_examples "open issues"
include_examples "closed issues"
include_examples "all issues"
end
end
end
context "when signed in as developer" do
before do
project.add_developer(user)
sign_in(user)
end
include_examples "public project"
include_examples "internal project"
end
context "when not signed in" do
include_examples "public project"
end
end
require 'spec_helper'
feature 'Milestones sorting', :js do
include SortingHelper
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
......
require "spec_helper"
# The main goal of this spec is not to check whether the sorting UI works, but
# to check if the sorting option set by user is being kept persisted while going through pages.
# The `it`s are named here by convention `starting point -> some pages -> final point`.
# All those specs are moved out to this spec intentionally to keep them all in one place.
describe "User sorts things" do
include Spec::Support::Helpers::Features::SortingHelpers
include Helpers::DashboardHelper
set(:project) { create(:project_empty_repo, :public) }
set(:current_user) { create(:user) } # Using `current_user` instead of just `user` because of the hardoced call in `assigned_mrs_dashboard_path` which is used below.
set(:issue) { create(:issue, project: project, author: current_user) }
set(:merge_request) { create(:merge_request, target_project: project, source_project: project, author: current_user) }
before do
project.add_developer(current_user)
sign_in(current_user)
end
it "issues -> project home page -> issues" do
sort_option = "Last updated"
visit(project_issues_path(project))
sort_by(sort_option)
visit(project_path(project))
visit(project_issues_path(project))
expect(find(".issues-filters")).to have_content(sort_option)
end
it "issues -> merge requests" do
sort_option = "Last updated"
visit(project_issues_path(project))
sort_by(sort_option)
visit(project_merge_requests_path(project))
expect(find(".issues-filters")).to have_content(sort_option)
end
it "merge requests -> dashboard merge requests" do
sort_option = "Last updated"
visit(project_merge_requests_path(project))
sort_by(sort_option)
visit(assigned_mrs_dashboard_path)
expect(find(".issues-filters")).to have_content(sort_option)
end
end
......@@ -2,7 +2,7 @@
# It takes a `issuable_type`, and expect an `issuable`.
shared_examples 'issuable record that supports quick actions in its description and notes' do |issuable_type|
include QuickActionsHelpers
include Spec::Support::Helpers::Features::NotesHelpers
let(:master) { create(:user) }
let(:project) do
......@@ -61,7 +61,7 @@ shared_examples 'issuable record that supports quick actions in its description
context 'with a note containing commands' do
it 'creates a note without the commands and interpret the commands accordingly' do
assignee = create(:user, username: 'bob')
write_note("Awesome!\n\n/assign @bob\n\n/label ~bug\n\n/milestone %\"ASAP\"")
add_note("Awesome!\n\n/assign @bob\n\n/label ~bug\n\n/milestone %\"ASAP\"")
expect(page).to have_content 'Awesome!'
expect(page).not_to have_content '/assign @bob'
......@@ -82,7 +82,7 @@ shared_examples 'issuable record that supports quick actions in its description
context 'with a note containing only commands' do
it 'does not create a note but interpret the commands accordingly' do
assignee = create(:user, username: 'bob')
write_note("/assign @bob\n\n/label ~bug\n\n/milestone %\"ASAP\"")
add_note("/assign @bob\n\n/label ~bug\n\n/milestone %\"ASAP\"")
expect(page).not_to have_content '/assign @bob'
expect(page).not_to have_content '/label ~bug'
......@@ -105,7 +105,7 @@ shared_examples 'issuable record that supports quick actions in its description
context "when current user can close #{issuable_type}" do
it "closes the #{issuable_type}" do
write_note("/close")
add_note("/close")
expect(page).not_to have_content '/close'
expect(page).to have_content 'Commands applied'
......@@ -125,7 +125,7 @@ shared_examples 'issuable record that supports quick actions in its description
end
it "does not close the #{issuable_type}" do
write_note("/close")
add_note("/close")
expect(page).not_to have_content 'Commands applied'
......@@ -142,7 +142,7 @@ shared_examples 'issuable record that supports quick actions in its description
context "when current user can reopen #{issuable_type}" do
it "reopens the #{issuable_type}" do
write_note("/reopen")
add_note("/reopen")
expect(page).not_to have_content '/reopen'
expect(page).to have_content 'Commands applied'
......@@ -162,7 +162,7 @@ shared_examples 'issuable record that supports quick actions in its description
end
it "does not reopen the #{issuable_type}" do
write_note("/reopen")
add_note("/reopen")
expect(page).not_to have_content 'Commands applied'
......@@ -174,7 +174,7 @@ shared_examples 'issuable record that supports quick actions in its description
context "with a note changing the #{issuable_type}'s title" do
context "when current user can change title of #{issuable_type}" do
it "reopens the #{issuable_type}" do
write_note("/title Awesome new title")
add_note("/title Awesome new title")
expect(page).not_to have_content '/title'
expect(page).to have_content 'Commands applied'
......@@ -194,7 +194,7 @@ shared_examples 'issuable record that supports quick actions in its description
end
it "does not change the #{issuable_type} title" do
write_note("/title Awesome new title")
add_note("/title Awesome new title")
expect(page).not_to have_content 'Commands applied'
......@@ -205,7 +205,7 @@ shared_examples 'issuable record that supports quick actions in its description
context "with a note marking the #{issuable_type} as todo" do
it "creates a new todo for the #{issuable_type}" do
write_note("/todo")
add_note("/todo")
expect(page).not_to have_content '/todo'
expect(page).to have_content 'Commands applied'
......@@ -236,7 +236,7 @@ shared_examples 'issuable record that supports quick actions in its description
expect(todo.author).to eq master
expect(todo.user).to eq master
write_note("/done")
add_note("/done")
expect(page).not_to have_content '/done'
expect(page).to have_content 'Commands applied'
......@@ -249,7 +249,7 @@ shared_examples 'issuable record that supports quick actions in its description
it "creates a new todo for the #{issuable_type}" do
expect(issuable.subscribed?(master, project)).to be_falsy
write_note("/subscribe")
add_note("/subscribe")
expect(page).not_to have_content '/subscribe'
expect(page).to have_content 'Commands applied'
......@@ -266,7 +266,7 @@ shared_examples 'issuable record that supports quick actions in its description
it "creates a new todo for the #{issuable_type}" do
expect(issuable.subscribed?(master, project)).to be_truthy
write_note("/unsubscribe")
add_note("/unsubscribe")
expect(page).not_to have_content '/unsubscribe'
expect(page).to have_content 'Commands applied'
......@@ -277,7 +277,7 @@ shared_examples 'issuable record that supports quick actions in its description
context "with a note assigning the #{issuable_type} to the current user" do
it "assigns the #{issuable_type} to the current user" do
write_note("/assign me")
add_note("/assign me")
expect(page).not_to have_content '/assign me'
expect(page).to have_content 'Commands applied'
......
# These helpers allow you to manipulate with notes.
#
# Usage:
# describe "..." do
# include Spec::Support::Helpers::Features::NotesHelpers
# ...
#
# add_note("Hello world!")
#
module Spec
module Support
module Helpers
module Features
module NotesHelpers
def add_note(text)
Sidekiq::Testing.fake! do
page.within(".js-main-target-form") do
fill_in("note[note]", with: text)
find(".js-comment-submit-button").click
end
end
end
end
end
end
end
end
# These helpers allow you to manipulate with sorting features.
#
# Usage:
# describe "..." do
# include Spec::Support::Helpers::Features::SortingHelpers
# ...
#
# sort_by("Last updated")
#
module Spec
module Support
module Helpers
module Features
module SortingHelpers
def sort_by(value)
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link(value)
end
end
end
end
end
end
end
RSpec::Matchers.define :have_header_with_correct_id_and_link do |level, text, id, parent = ".wiki"|
match do |actual|
node = find("#{parent} h#{level} a#user-content-#{id}")
expect(node[:href]).to end_with("##{id}")
# Work around a weird Capybara behavior where calling `parent` on a node
# returns the whole document, not the node's actual parent element
expect(find(:xpath, "#{node.path}/..").text).to eq(text)
end
end
module QuickActionsHelpers
def write_note(text)
Sidekiq::Testing.fake! do
page.within('.js-main-target-form') do
fill_in 'note[note]', with: text
find('.js-comment-submit-button').click
end
end
end
end
# Helper allows you to sort items
#
# Params
# value - value for sorting
#
# Usage:
# include SortingHelper
#
# sorting_by('Oldest updated')
#
module SortingHelper
def sorting_by(value)
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link value
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