diff options
Diffstat (limited to 'features')
96 files changed, 2604 insertions, 201 deletions
diff --git a/features/admin/appearance.feature b/features/admin/appearance.feature new file mode 100644 index 00000000000..5c1dd7531c1 --- /dev/null +++ b/features/admin/appearance.feature @@ -0,0 +1,37 @@ +Feature: Admin Appearance + Scenario: Create new appearance + Given I sign in as an admin + And I visit admin appearance page + When submit form with new appearance + Then I should be redirected to admin appearance page + And I should see newly created appearance + + Scenario: Preview appearance + Given application has custom appearance + And I sign in as an admin + When I visit admin appearance page + And I click preview button + Then I should see a customized appearance + + Scenario: Custom sign-in page + Given application has custom appearance + When I visit login page + Then I should see a customized appearance + + Scenario: Appearance logo + Given application has custom appearance + And I sign in as an admin + And I visit admin appearance page + When I attach a logo + Then I should see a logo + And I remove the logo + Then I should see logo removed + + Scenario: Header logos + Given application has custom appearance + And I sign in as an admin + And I visit admin appearance page + When I attach header logos + Then I should see header logos + And I remove the header logos + Then I should see header logos removed diff --git a/features/admin/broadcast_messages.feature b/features/admin/broadcast_messages.feature index b2c3112320a..4f9c651561e 100644 --- a/features/admin/broadcast_messages.feature +++ b/features/admin/broadcast_messages.feature @@ -2,16 +2,11 @@ Feature: Admin Broadcast Messages Background: Given I sign in as an admin - And application already has admin messages + And application already has a broadcast message And I visit admin messages page Scenario: See broadcast messages list - Then I should be all broadcast messages - - Scenario: Create a broadcast message - When submit form with new broadcast message - Then I should be redirected to admin messages page - And I should see newly created broadcast message + Then I should see all broadcast messages Scenario: Create a customized broadcast message When submit form with new customized broadcast message @@ -19,3 +14,20 @@ Feature: Admin Broadcast Messages And I should see newly created broadcast message Then I visit dashboard page And I should see a customized broadcast message + + Scenario: Edit an existing broadcast message + When I edit an existing broadcast message + And I change the broadcast message text + Then I should be redirected to admin messages page + And I should see the updated broadcast message + + Scenario: Remove an existing broadcast message + When I remove an existing broadcast message + Then I should be redirected to admin messages page + And I should not see the removed broadcast message + + @javascript + Scenario: Live preview a customized broadcast message + When I visit admin messages page + And I enter a broadcast message with Markdown + Then I should see a live preview of the rendered broadcast message diff --git a/features/admin/groups.feature b/features/admin/groups.feature index 2edb3964f70..ab7de7ac315 100644 --- a/features/admin/groups.feature +++ b/features/admin/groups.feature @@ -21,6 +21,11 @@ Feature: Admin Groups When I select user "John Doe" from user list as "Reporter" Then I should see "John Doe" in team list in every project as "Reporter" + Scenario: Shared projects + Given group has shared projects + When I visit group page + Then I should see project shared with group + @javascript Scenario: Remove user from group Given we have user "John Doe" in group diff --git a/features/admin/spam_logs.feature b/features/admin/spam_logs.feature new file mode 100644 index 00000000000..92a5389e3a4 --- /dev/null +++ b/features/admin/spam_logs.feature @@ -0,0 +1,8 @@ +Feature: Admin spam logs + Background: + Given I sign in as an admin + And spam logs exist + + Scenario: Browse spam logs + When I visit spam logs page + Then I should see list of spam logs diff --git a/features/dashboard/archived_projects.feature b/features/dashboard/archived_projects.feature index 69b3a776441..bed9282f1c6 100644 --- a/features/dashboard/archived_projects.feature +++ b/features/dashboard/archived_projects.feature @@ -10,3 +10,8 @@ Feature: Dashboard Archived Projects Scenario: I should see non-archived projects on dashboard Then I should see "Shop" project link And I should not see "Forum" project link + + Scenario: I toggle show of archived projects on dashboard + When I click "Show archived projects" link + Then I should see "Shop" project link + And I should see "Forum" project link diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature index b667b587c5b..c3b3577c449 100644 --- a/features/dashboard/dashboard.feature +++ b/features/dashboard/dashboard.feature @@ -41,3 +41,33 @@ Feature: Dashboard And user with name "John Doe" left project "Shop" When I visit dashboard activity page Then I should see "John Doe left project Shop" event + + @javascript + Scenario: Sorting Issues + Given I visit dashboard issues page + And I sort the list by "Oldest updated" + And I visit dashboard activity page + And I visit dashboard issues page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Project's issues after sorting + Given I visit dashboard issues page + And I sort the list by "Oldest updated" + And I visit project "Shop" issues page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Sorting Merge Requests + Given I visit dashboard merge requests page + And I sort the list by "Oldest updated" + And I visit dashboard activity page + And I visit dashboard merge requests page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Project's merge requests after sorting + Given I visit dashboard merge requests page + And I sort the list by "Oldest updated" + And I visit project "Shop" merge requests page + Then The list should be sorted by "Oldest updated" diff --git a/features/dashboard/event_filters.feature b/features/dashboard/event_filters.feature index 96399ea21a6..8c3ff64164f 100644 --- a/features/dashboard/event_filters.feature +++ b/features/dashboard/event_filters.feature @@ -43,10 +43,16 @@ Feature: Event Filters And I should not see new member event When I click "team" event filter And I visit dashboard activity page - Then I should see push event + Then I should not see push event And I should see new member event And I should not see merge request event When I click "push" event filter - Then I should not see push event - And I should see new member event + And I visit dashboard activity page + Then I should see push event + And I should not see new member event And I should not see merge request event + When I click "merge" event filter + And I visit dashboard activity page + Then I should see merge request event + And I should not see push event + And I should not see new member event diff --git a/features/dashboard/todos.feature b/features/dashboard/todos.feature new file mode 100644 index 00000000000..1e7b1b50d64 --- /dev/null +++ b/features/dashboard/todos.feature @@ -0,0 +1,38 @@ +@dashboard +Feature: Dashboard Todos + Background: + Given I sign in as a user + And I own project "Shop" + And "John Doe" is a developer of project "Shop" + And "Mary Jane" is a developer of project "Shop" + And "Mary Jane" owns private project "Enterprise" + And I am a developer of project "Enterprise" + And I have todos + And I visit dashboard todos page + + @javascript + Scenario: I mark todos as done + Then I should see todos assigned to me + And I mark the todo as done + And I click on the "Done" tab + Then I should see all todos marked as done + + @javascript + Scenario: I filter by project + Given I filter by "Enterprise" + Then I should not see todos + + @javascript + Scenario: I filter by author + Given I filter by "John Doe" + Then I should not see todos related to "Mary Jane" in the list + + @javascript + Scenario: I filter by type + Given I filter by "Issue" + Then I should not see todos related to "Merge Requests" in the list + + @javascript + Scenario: I filter by action + Given I filter by "Mentioned" + Then I should not see todos related to "Assignments" in the list diff --git a/features/explore/groups.feature b/features/explore/groups.feature index a42e59c98f2..5fc9b135601 100644 --- a/features/explore/groups.feature +++ b/features/explore/groups.feature @@ -105,15 +105,6 @@ Feature: Explore Groups When I visit the public groups area Then I should see group "TestGroup" - Scenario: I should not see group with internal project in public groups area - Given group "TestGroup" has internal project "Internal" - When I visit the public groups area - Then I should not see group "TestGroup" - - Scenario: I should not see group with private project in public groups area - When I visit the public groups area - Then I should not see group "TestGroup" - Scenario: I should see group with public project in public groups area as user Given group "TestGroup" has public project "Community" When I sign in as a user @@ -125,9 +116,3 @@ Feature: Explore Groups When I sign in as a user And I visit the public groups area Then I should see group "TestGroup" - - Scenario: I should not see group with private project in public groups area as user - When I sign in as a user - And I visit the public groups area - Then I should not see group "TestGroup" - diff --git a/features/explore/projects.feature b/features/explore/projects.feature index 629859e960d..092e18d1b86 100644 --- a/features/explore/projects.feature +++ b/features/explore/projects.feature @@ -87,6 +87,7 @@ Feature: Explore Projects Scenario: I visit public project issues page as a non authorized user Given I visit project "Community" page + Then I should not see command line instructions And I visit "Community" issues page Then I should see list of issues for "Community" project @@ -139,4 +140,4 @@ Feature: Explore Projects When I visit the explore starred projects Then I should see project "Community" And I should see project "Internal" - And I should see project "Archive" + And I should not see project "Archive" diff --git a/features/group/milestones.feature b/features/group/milestones.feature index 62ea66a783c..d6c05df9840 100644 --- a/features/group/milestones.feature +++ b/features/group/milestones.feature @@ -28,3 +28,20 @@ Feature: Group Milestones And I fill milestone name When I press create mileston button Then milestone in each project should be created + + Scenario: I should see Issues listed with labels + Given Group has projects with milestones + When I visit group "Owned" page + And I click on group milestones + And I click on one group milestone + Then I should see the "bug" label + And I should see the "feature" label + And I should see the project name in the Issue row + + Scenario: I should see the Labels tab + Given Group has projects with milestones + When I visit group "Owned" page + And I click on group milestones + And I click on one group milestone + And I click on the "Labels" tab + Then I should see the list of labels diff --git a/features/groups.feature b/features/groups.feature index c803e952980..419a5d3963d 100644 --- a/features/groups.feature +++ b/features/groups.feature @@ -3,6 +3,10 @@ Feature: Groups Given I sign in as "John Doe" And "John Doe" is owner of group "Owned" + Scenario: I should not see a group if it does not exist + When I visit group "NonExistentGroup" page + Then page status code should be 404 + Scenario: I should have back to group button When I visit group "Owned" page Then I should see back to dashboard button @@ -11,6 +15,10 @@ Feature: Groups Scenario: I should see group "Owned" dashboard list When I visit group "Owned" page Then I should see group "Owned" projects list + + @javascript + Scenario: I should see group "Owned" activity feed + When I visit group "Owned" activity page And I should see projects activity feed Scenario: I should see group "Owned" issues list @@ -18,11 +26,23 @@ Feature: Groups When I visit group "Owned" issues page Then I should see issues from group "Owned" assigned to me + Scenario: I should not see issues from archived project in "Owned" group issues list + Given Group "Owned" has archived project + And the archived project have some issues + When I visit group "Owned" issues page + Then I should not see issues from the archived project + Scenario: I should see group "Owned" merge requests list Given project from group "Owned" has merge requests assigned to me When I visit group "Owned" merge requests page Then I should see merge requests from group "Owned" assigned to me + Scenario: I should not see merge requests from archived project in "Owned" group merge requests list + Given Group "Owned" has archived project + And the archived project have some merge_requests + When I visit group "Owned" merge requests page + Then I should not see merge requests from the archived project + Scenario: I should see edit group "Owned" page When I visit group "Owned" settings page And I change group "Owned" name to "new-name" diff --git a/features/login_form.feature b/features/login_form.feature deleted file mode 100644 index b4d95754482..00000000000 --- a/features/login_form.feature +++ /dev/null @@ -1,5 +0,0 @@ -Feature: Login form - Scenario: I see crowd form - Given Crowd integration enabled - When I visit sign in page - Then I should see Crowd login form
\ No newline at end of file diff --git a/features/profile/profile.feature b/features/profile/profile.feature index 168d9d30b50..447dd92a458 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -76,8 +76,7 @@ Feature: Profile Scenario: I can manage application Given I visit profile applications page - Then I click on new application button - And I should see application form + Then I should see application form Then I fill application form out and submit And I see application Then I click edit diff --git a/features/profile/ssh_keys.feature b/features/profile/ssh_keys.feature index 581503fc5f9..b0d5b748916 100644 --- a/features/profile/ssh_keys.feature +++ b/features/profile/ssh_keys.feature @@ -9,7 +9,7 @@ Feature: Profile SSH Keys Then I should see my ssh keys Scenario: Add new ssh key - Given I click link "Add new" + Given I should see new ssh key form And I submit new ssh key "Laptop" Then I should see new ssh key "Laptop" diff --git a/features/project/badges/build.feature b/features/project/badges/build.feature new file mode 100644 index 00000000000..bcf80ed620e --- /dev/null +++ b/features/project/badges/build.feature @@ -0,0 +1,27 @@ +Feature: Project Badges Build + Background: + Given I sign in as a user + And I own a project + And project has CI enabled + And project has a recent build + + Scenario: I want to see a badge for successfully built project + Given recent build is successful + When I display builds badge for a master branch + Then I should see a build success badge + + Scenario: I want to see a badge for project with failed builds + Given recent build failed + When I display builds badge for a master branch + Then I should see a build failed badge + + Scenario: I want to see a badge for project with running builds + Given recent build is successful + And project has another build that is running + When I display builds badge for a master branch + Then I should see a build running badge + + Scenario: I want to see a fresh badge on each request + Given recent build is successful + When I display builds badge for a master branch + Then I should see a badge that has not been cached diff --git a/features/project/builds/artifacts.feature b/features/project/builds/artifacts.feature new file mode 100644 index 00000000000..52dc15f2eb6 --- /dev/null +++ b/features/project/builds/artifacts.feature @@ -0,0 +1,62 @@ +Feature: Project Builds Artifacts + Background: + Given I sign in as a user + And I own a project + And project has CI enabled + And project has a recent build + + Scenario: I download build artifacts + Given recent build has artifacts available + When I visit recent build details page + And I click artifacts download button + Then download of build artifacts archive starts + + Scenario: I browse build artifacts + Given recent build has artifacts available + And recent build has artifacts metadata available + When I visit recent build details page + And I click artifacts browse button + Then I should see content of artifacts archive + + Scenario: I browse subdirectory of build artifacts + Given recent build has artifacts available + And recent build has artifacts metadata available + When I visit recent build details page + And I click artifacts browse button + And I click link to subdirectory within build artifacts + Then I should see content of subdirectory within artifacts archive + + Scenario: I browse directory with UTF-8 characters in name + Given recent build has artifacts available + And recent build has artifacts metadata available + And recent build artifacts contain directory with UTF-8 characters + When I visit recent build details page + And I click artifacts browse button + And I navigate to directory with UTF-8 characters in name + Then I should see content of directory with UTF-8 characters in name + + Scenario: I try to browse directory with invalid UTF-8 characters in name + Given recent build has artifacts available + And recent build has artifacts metadata available + And recent build artifacts contain directory with invalid UTF-8 characters + When I visit recent build details page + And I click artifacts browse button + And I navigate to parent directory of directory with invalid name + Then I should not see directory with invalid name on the list + + Scenario: I download a single file from build artifacts + Given recent build has artifacts available + And recent build has artifacts metadata available + When I visit recent build details page + And I click artifacts browse button + And I click a link to file within build artifacts + Then download of a file extracted from build artifacts should start + + @javascript + Scenario: I click on a row in an artifacts table + Given recent build has artifacts available + And recent build has artifacts metadata available + When I visit recent build details page + And I click artifacts browse button + And I click a first row within build artifacts table + Then page with a coresponding path is loading diff --git a/features/project/builds/permissions.feature b/features/project/builds/permissions.feature new file mode 100644 index 00000000000..3c7f72335d9 --- /dev/null +++ b/features/project/builds/permissions.feature @@ -0,0 +1,53 @@ +Feature: Project Builds Permissions + Background: + Given I sign in as a user + And project exists in some group namespace + And project has CI enabled + And project has a recent build + + Scenario: I try to visit build details as guest + Given I am member of a project with a guest role + When I visit recent build details page + Then page status code should be 404 + + Scenario: I try to visit project builds page as guest + Given I am member of a project with a guest role + When I visit project builds page + Then page status code should be 404 + + Scenario: I try to visit build details of internal project without access to builds + Given The project is internal + And public access for builds is disabled + When I visit recent build details page + Then page status code should be 404 + + Scenario: I try to visit internal project builds page without access to builds + Given The project is internal + And public access for builds is disabled + When I visit project builds page + Then page status code should be 404 + + Scenario: I try to visit build details of internal project with access to builds + Given The project is internal + And public access for builds is enabled + When I visit recent build details page + Then I see details of a build + And I see build trace + + Scenario: I try to visit internal project builds page with access to builds + Given The project is internal + And public access for builds is enabled + When I visit project builds page + Then I see the build + + Scenario: I try to download build artifacts as guest + Given I am member of a project with a guest role + And recent build has artifacts available + When I access artifacts download page + Then page status code should be 404 + + Scenario: I try to download build artifacts as reporter + Given I am member of a project with a reporter role + And recent build has artifacts available + When I access artifacts download page + Then download of build artifacts archive starts diff --git a/features/project/builds/summary.feature b/features/project/builds/summary.feature new file mode 100644 index 00000000000..3c029a973df --- /dev/null +++ b/features/project/builds/summary.feature @@ -0,0 +1,26 @@ +Feature: Project Builds Summary + Background: + Given I sign in as a user + And I own a project + And project has CI enabled + And project has coverage enabled + And project has a recent build + + Scenario: I browse build details page + When I visit recent build details page + Then I see details of a build + And I see build trace + + Scenario: I browse project builds page + When I visit project builds page + Then I see coverage + Then I see button to CI Lint + + Scenario: I erase a build + Given recent build is successful + And recent build has a build trace + When I visit recent build details page + And I click erase build button + Then recent build has been erased + And recent build summary does not have artifacts widget + And recent build summary contains information saying that build has been erased diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature index 5bb2d0e976b..a95df038357 100644 --- a/features/project/commits/commits.feature +++ b/features/project/commits/commits.feature @@ -7,6 +7,26 @@ Feature: Project Commits Scenario: I browse commits list for master branch Then I see project commits + And I should not see button to create a new merge request + Then I click the "Compare" tab + And I should not see button to create a new merge request + + Scenario: I browse commits list for feature branch without a merge request + Given I visit commits list page for feature branch + Then I see feature branch commits + And I see button to create a new merge request + Then I click the "Compare" tab + And I see button to create a new merge request + + Scenario: I browse commits list for feature branch with an open merge request + Given project have an open merge request + And I visit commits list page for feature branch + Then I see feature branch commits + And I should not see button to create a new merge request + And I should see button to the merge request + Then I click the "Compare" tab + And I should not see button to create a new merge request + And I should see button to the merge request Scenario: I browse atom feed of commits list for master branch Given I click atom feed link @@ -31,6 +51,22 @@ Feature: Project Commits Then I see inline diff button @javascript + Scenario: I compare branches without a merge request + Given I visit compare refs page + And I fill compare fields with branches + Then I see compared branches + And I see button to create a new merge request + + @javascript + Scenario: I compare branches with an open merge request + Given project have an open merge request + And I visit compare refs page + And I fill compare fields with branches + Then I see compared branches + And I should not see button to create a new merge request + And I should see button to the merge request + + @javascript Scenario: I compare refs Given I visit compare refs page And I fill compare fields with refs @@ -55,3 +91,8 @@ Feature: Project Commits Scenario: I browse a commit with an image Given I visit a commit with an image that changed Then The diff links to both the previous and current image + + @javascript + Scenario: I filter commits by message + When I search "submodules" commits + Then I should see only "submodules" commits diff --git a/features/project/commits/revert.feature b/features/project/commits/revert.feature new file mode 100644 index 00000000000..7a2effafe03 --- /dev/null +++ b/features/project/commits/revert.feature @@ -0,0 +1,28 @@ +@project_commits +Feature: Revert Commits + Background: + Given I sign in as a user + And I own a project + And I visit my project's commits page + + Scenario: I revert a commit + Given I click on commit link + And I click on the revert button + And I revert the changes directly + Then I should see the revert commit notice + + Scenario: I revert a commit that was previously reverted + Given I click on commit link + And I click on the revert button + And I revert the changes directly + And I visit my project's commits page + And I click on commit link + And I click on the revert button + And I revert the changes directly + Then I should see a revert error + + Scenario: I revert a commit in a new merge request + Given I click on commit link + And I click on the revert button + And I revert the changes in a new merge request + Then I should see the new merge request notice diff --git a/features/project/find_file.feature b/features/project/find_file.feature new file mode 100644 index 00000000000..ae8fa245923 --- /dev/null +++ b/features/project/find_file.feature @@ -0,0 +1,42 @@ +@dashboard +Feature: Project Find File + Background: + Given I sign in as a user + And I own a project + And I visit my project's files page + + @javascript + Scenario: Navigate to find file by shortcut + Given I press "t" + Then I should see "find file" page + + Scenario: Navigate to find file + Given I click Find File button + Then I should see "find file" page + + @javascript + Scenario: I search file + Given I visit project find file page + And I fill in file find with "change" + Then I should not see ".gitignore" in files + And I should not see ".gitmodules" in files + And I should see "CHANGELOG" in files + And I should not see "VERSION" in files + + @javascript + Scenario: I search file that not exist + Given I visit project find file page + And I fill in file find with "asdfghjklqwertyuizxcvbnm" + Then I should not see ".gitignore" in files + And I should not see ".gitmodules" in files + And I should not see "CHANGELOG" in files + And I should not see "VERSION" in files + + @javascript + Scenario: I search file that partially matches + Given I visit project find file page + And I fill in file find with "git" + Then I should see ".gitignore" in files + And I should see ".gitmodules" in files + And I should not see "CHANGELOG" in files + And I should not see "VERSION" in files diff --git a/features/project/fork.feature b/features/project/fork.feature index 22f68e5b340..ca3f2771aa5 100644 --- a/features/project/fork.feature +++ b/features/project/fork.feature @@ -14,3 +14,36 @@ Feature: Project Fork And I click link "Fork" When I fork to my namespace Then I should see a "Name has already been taken" warning + + Scenario: Merge request on canonical repo goes to fork merge request page + Given I click link "Fork" + And I fork to my namespace + Then I should see the forked project page + When I visit project "Shop" page + Then I should see "New merge request" + And I goto the Merge Requests page + Then I should see "New merge request" + And I click link "New merge request" + Then I should see the new merge request page for my namespace + + Scenario: Viewing forks of a Project + Given I click link "Fork" + When I fork to my namespace + And I visit the forks page of the "Shop" project + Then I should see my fork on the list + + Scenario: Viewing forks of a Project that has no repo + Given I click link "Fork" + When I fork to my namespace + And I make forked repo invalid + And I visit the forks page of the "Shop" project + Then I should see my fork on the list + + Scenario: Viewing private forks of a Project + Given There is an existent fork of the "Shop" project + And I click link "Fork" + When I fork to my namespace + And I visit the forks page of the "Shop" project + Then I should see my fork on the list + And I should not see the other fork listed + And I should see a private fork notice diff --git a/features/project/group_links.feature b/features/project/group_links.feature new file mode 100644 index 00000000000..2657c4487ad --- /dev/null +++ b/features/project/group_links.feature @@ -0,0 +1,16 @@ +Feature: Project Group Links + Background: + Given I sign in as a user + And I own project "Shop" + And project "Shop" is shared with group "Ops" + And project "Shop" is not shared with group "Market" + And I visit project group links page + + Scenario: I should see list of groups + Then I should see project already shared with group "Ops" + Then I should see project is not shared with group "Market" + + @javascript + Scenario: I share project with group + When I select group "Market" for share + Then I should see project is shared with group "Market" diff --git a/features/project/issues/award_emoji.feature b/features/project/issues/award_emoji.feature index 9a06fdc2ee6..f0fd414a9f9 100644 --- a/features/project/issues/award_emoji.feature +++ b/features/project/issues/award_emoji.feature @@ -7,20 +7,35 @@ Feature: Award Emoji And I visit "Bugfix" issue page @javascript - Scenario: I add and remove award in the issue + Scenario: I repeatedly add and remove thumbsup award in the issue + Given I click the thumbsup award Emoji + Then I have award added + Given I click the thumbsup award Emoji + Then I have no awards added + Given I click the thumbsup award Emoji + Then I have award added + + @javascript + Scenario: I add and remove custom award in the issue Given I click to emoji-picker - And I click to emoji in the picker + Then The emoji menu is visible + And The search field is focused + Then I click to emoji in the picker Then I have award added And I can remove it by clicking to icon @javascript Scenario: I can see the list of emoji categories Given I click to emoji-picker + Then The emoji menu is visible + And The search field is focused Then I can see the activity and food categories @javascript Scenario: I can search emoji Given I click to emoji-picker + Then The emoji menu is visible + And The search field is focused And I search "hand" Then I see search result for "hand" diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature index ab234bc7507..ff21c7d1b83 100644 --- a/features/project/issues/issues.feature +++ b/features/project/issues/issues.feature @@ -25,9 +25,16 @@ Feature: Project Issues Scenario: I visit issue page Given I click link "Release 0.4" Then I should see issue "Release 0.4" + And I should see "1 of 2" in the sidebar + + Scenario: I navigate between issues + Given I click link "Release 0.4" + Then I click link "Next" in the sidebar + Then I should see issue "Tweet control" + And I should see "2 of 2" in the sidebar @javascript - Scenario: I visit issue page + Scenario: I filter by author Given I add a user to project "Shop" And I click "author" dropdown Then I see current user as the first user @@ -52,6 +59,38 @@ Feature: Project Issues 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 "Oldest updated" + And I visit my project's home page + And I visit project "Shop" issues page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Merge Requests after being sorted the list + Given I visit project "Shop" issues page + And I sort the list by "Oldest updated" + And I visit project "Shop" merge requests page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Merge Requests from a differente Project after sorting + Given I visit project "Shop" merge requests page + And I sort the list by "Oldest updated" + And I visit dashboard merge requests page + Then The list should be sorted by "Oldest 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 "Most popular" + Then The list should be sorted by "Most popular" + And I sort the list by "Least popular" + Then The list should be sorted by "Least popular" + + @javascript Scenario: I search issue Given I fill in issue search with "Re" Then I should see "Release 0.4" in issues diff --git a/features/project/issues/references.feature b/features/project/issues/references.feature new file mode 100644 index 00000000000..4ae2d653337 --- /dev/null +++ b/features/project/issues/references.feature @@ -0,0 +1,33 @@ +@project_issues +Feature: Project Issues References + Background: + Given I sign in as "John Doe" + And public project "Community" + And "John Doe" owns public project "Community" + And project "Community" has "Community issue" open issue + And I logout + And I sign in as "Mary Jane" + And private project "Enterprise" + And "Mary Jane" owns private project "Enterprise" + And project "Enterprise" has "Enterprise issue" open issue + And project "Enterprise" has "Enterprise fix" open merge request + And I visit issue page "Enterprise issue" + And I leave a comment referencing issue "Community issue" + And I visit merge request page "Enterprise fix" + And I leave a comment referencing issue "Community issue" + And I logout + + @javascript + Scenario: Viewing the public issue as a "John Doe" + Given I sign in as "John Doe" + When I visit issue page "Community issue" + Then I should not see any related merge requests + And I should see no notes at all + + @javascript + Scenario: Viewing the public issue as "Mary Jane" + Given I sign in as "Mary Jane" + When I visit issue page "Community issue" + Then I should see the "Enterprise fix" related merge request + And I should see a note linking to "Enterprise fix" merge request + And I should see a note linking to "Enterprise issue" issue diff --git a/features/project/labels.feature b/features/project/labels.feature new file mode 100644 index 00000000000..955bc3d8b1b --- /dev/null +++ b/features/project/labels.feature @@ -0,0 +1,15 @@ +@labels +Feature: Labels + Background: + Given I sign in as a user + And I own project "Shop" + And project "Shop" has labels: "bug", "feature", "enhancement" + When I visit project "Shop" labels page + + @javascript + Scenario: I can subscribe to a label + Then I should see that I am not subscribed to the "bug" label + When I click button "Subscribe" for the "bug" label + Then I should see that I am subscribed to the "bug" label + When I click button "Unsubscribe" for the "bug" label + Then I should see that I am not subscribed to the "bug" label diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index aa9078b878f..74685d24a7d 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -26,6 +26,16 @@ Feature: Project Merge Requests When I visit project "Shop" merge requests page Then I should see "other_branch" branch + Scenario: I should not see the numbers of diverged commits if the branch is rebased on the target + Given project "Shop" have "Bug NS-07" open merge request with rebased branch + When I visit merge request page "Bug NS-07" + Then I should not see the diverged commits count + + Scenario: I should see the numbers of diverged commits if the branch diverged from the target + Given project "Shop" have "Bug NS-08" open merge request with diverged branch + When I visit merge request page "Bug NS-08" + Then I should see the diverged commits count + Scenario: I should see rejected merge requests Given I click link "Closed" Then I should see "Feature NS-03" in merge requests @@ -36,9 +46,17 @@ Feature: Project Merge Requests Then I should see "Feature NS-03" in merge requests And I should see "Bug NS-04" in merge requests - Scenario: I visit merge request page + Scenario: I visit an open merge request page Given I click link "Bug NS-04" Then I should see merge request "Bug NS-04" + And I should see "1 of 1" in the sidebar + + Scenario: I visit a merged merge request page + Given project "Shop" have "Feature NS-05" merged merge request + And I click link "Merged" + And I click link "Feature NS-05" + Then I should see merge request "Feature NS-05" + And I should see "3 of 3" in the sidebar Scenario: I close merge request page Given I click link "Bug NS-04" @@ -76,6 +94,39 @@ Feature: Project Merge Requests Then I should see comment "XML attached" @javascript + Scenario: Visiting Merge Requests after being sorted the list + Given I visit project "Shop" merge requests page + And I sort the list by "Oldest updated" + And I visit my project's home page + And I visit project "Shop" merge requests page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Issues after being sorted the list + Given I visit project "Shop" merge requests page + And I sort the list by "Oldest updated" + And I visit project "Shop" issues page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Visiting Merge Requests from a differente Project after sorting + Given I visit project "Shop" merge requests page + And I sort the list by "Oldest updated" + And I visit dashboard merge requests page + Then The list should be sorted by "Oldest updated" + + @javascript + Scenario: Sort merge requests by upvotes/downvotes + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And project "Shop" have "Bug NS-06" open merge request + And merge request "Bug NS-04" have 2 upvotes and 1 downvote + And merge request "Bug NS-06" have 1 upvote and 2 downvotes + And I sort the list by "Most popular" + Then The list should be sorted by "Most popular" + And I sort the list by "Least popular" + Then The list should be sorted by "Least popular" + + @javascript Scenario: I comment on a merge request diff Given project "Shop" have "Bug NS-05" open merge request with diffs inside And I visit merge request page "Bug NS-05" @@ -83,6 +134,15 @@ Feature: Project Merge Requests And I leave a comment like "Line is wrong" on diff And I switch to the merge request's comments tab Then I should see a discussion has started on diff + And I should see a badge of "1" next to the discussion link + + @javascript + Scenario: I see a new comment on merge request diff from another user in the discussion tab + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And I visit merge request page "Bug NS-05" + And user "John Doe" leaves a comment like "Line is wrong" on diff + Then I should see a discussion by user "John Doe" has started on diff + And I should see a badge of "1" next to the discussion link @javascript Scenario: I edit a comment on a merge request diff @@ -100,9 +160,11 @@ Feature: Project Merge Requests And I visit merge request page "Bug NS-05" And I click on the Changes tab And I leave a comment like "Line is wrong" on diff + And I should see a badge of "1" next to the discussion link And I delete the comment "Line is wrong" on diff And I click on the Discussion tab Then I should not see any discussion + And I should see a badge of "0" next to the discussion link @javascript Scenario: I comment on a line of a commit in merge request diff --git a/features/project/merge_requests/references.feature b/features/project/merge_requests/references.feature new file mode 100644 index 00000000000..571612261a9 --- /dev/null +++ b/features/project/merge_requests/references.feature @@ -0,0 +1,31 @@ +@project_merge_requests +Feature: Project Merge Requests References + Background: + Given I sign in as "John Doe" + And public project "Community" + And "John Doe" owns public project "Community" + And project "Community" has "Community fix" open merge request + And I logout + And I sign in as "Mary Jane" + And private project "Enterprise" + And "Mary Jane" owns private project "Enterprise" + And project "Enterprise" has "Enterprise issue" open issue + And project "Enterprise" has "Enterprise fix" open merge request + And I visit issue page "Enterprise issue" + And I leave a comment referencing issue "Community fix" + And I visit merge request page "Enterprise fix" + And I leave a comment referencing issue "Community fix" + And I logout + + @javascript + Scenario: Viewing the public issue as a "John Doe" + Given I sign in as "John Doe" + When I visit issue page "Community fix" + Then I should see no notes at all + + @javascript + Scenario: Viewing the public issue as "Mary Jane" + Given I sign in as "Mary Jane" + When I visit issue page "Community fix" + And I should see a note linking to "Enterprise fix" merge request + And I should see a note linking to "Enterprise issue" issue diff --git a/features/project/merge_requests/revert.feature b/features/project/merge_requests/revert.feature new file mode 100644 index 00000000000..d767b088883 --- /dev/null +++ b/features/project/merge_requests/revert.feature @@ -0,0 +1,30 @@ +@project_merge_requests +Feature: Revert Merge Requests + Background: + Given There is an open Merge Request + And I am signed in as a developer of the project + And I am on the Merge Request detail page + And I click on Accept Merge Request + + @javascript + Scenario: I revert a merge request + Given I click on the revert button + And I revert the changes directly + Then I should see the revert merge request notice + + @javascript + Scenario: I revert a merge request that was previously reverted + Given I click on the revert button + And I revert the changes directly + And I am on the Merge Request detail page + And I click on the revert button + And I revert the changes directly + Then I should see a revert error + + @javascript + Scenario: I revert a merge request in a new merge request + Given I click on the revert button + And I am on the Merge Request detail page + And I click on the revert button + And I revert the changes in a new merge request + Then I should see the new merge request notice diff --git a/features/project/milestone.feature b/features/project/milestone.feature new file mode 100644 index 00000000000..713f0f3b979 --- /dev/null +++ b/features/project/milestone.feature @@ -0,0 +1,24 @@ +Feature: Project Milestone + Background: + Given I sign in as a user + And I own project "Shop" + And project "Shop" has labels: "bug", "feature", "enhancement" + And project "Shop" has milestone "v2.2" + And milestone has issue "Bugfix1" with labels: "bug", "feature" + And milestone has issue "Bugfix2" with labels: "bug", "enhancement" + + + @javascript + Scenario: Listing issues from issues tab + Given I visit project "Shop" milestones page + And I click link "v2.2" + Then I should see the labels "bug", "enhancement" and "feature" + And I should see the "bug" label listed only once + + @javascript + Scenario: Listing labels from labels tab + Given I visit project "Shop" milestones page + And I click link "v2.2" + And I click link "Labels" + Then I should see the list of labels + And I should see the labels "bug", "enhancement" and "feature" diff --git a/features/project/network_graph.feature b/features/project/network_graph.feature index 6cc89a15a78..89a02706bd2 100644 --- a/features/project/network_graph.feature +++ b/features/project/network_graph.feature @@ -34,9 +34,10 @@ Feature: Project Network Graph @javascript Scenario: I should filter selected tag When I switch ref to "v1.0.0" + Then page should have "v1.0.0" in title Then page should have content not containing "v1.0.0" When click "Show only selected branch" checkbox - Then page should not have content not containing "v1.0.0" + Then page should only have content from "v1.0.0" When click "Show only selected branch" checkbox Then page should have content not containing "v1.0.0" diff --git a/features/project/project.feature b/features/project/project.feature index 1a53945eb04..f1f3ed26065 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -86,3 +86,9 @@ Feature: Project Given I click notifications drop down button When I choose Mention setting Then I should see Notification saved message + + Scenario: I should see command line instructions + Given I own an empty project + And I visit my empty project page + And I create bare repo + Then I should see command line instructions diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index a8c276b949e..1e09dbc4c8f 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -320,3 +320,13 @@ Feature: Project Source Browse Files Then I should see download link and object size And I should not see lfs pointer details And I should see buttons for allowed commands + + @javascript + Scenario: I preview an SVG file + Given I click on "Upload file" link in repo + And I upload a new SVG file + And I fill the upload file commit message + And I fill the new branch name + And I click on "Upload file" + Given I visit the SVG file + Then I can see the new rendered SVG image diff --git a/features/project/team_management.feature b/features/project/team_management.feature index 06fb45c8bde..5888662fc3f 100644 --- a/features/project/team_management.feature +++ b/features/project/team_management.feature @@ -39,3 +39,8 @@ Feature: Project Team Management And I click link "Import team from another project" And I submit "Website" project for import team Then I should see "Mike" in team list as "Reporter" + + Scenario: See all members of projects shared group + Given I share project with group "OpenSource" + And I visit project "Shop" team page + Then I should see "Opensource" group user listing diff --git a/features/project/wiki.feature b/features/project/wiki.feature index af970ecf2d0..d4811b1ff54 100644 --- a/features/project/wiki.feature +++ b/features/project/wiki.feature @@ -70,11 +70,6 @@ Feature: Project Wiki Then I should see non-escaped link in the pages list @javascript - Scenario: Creating an invalid new page - Given I create a New page with an invalid name - Then I should see an error message - - @javascript Scenario: Edit Wiki page that has a path Given I create a New page with paths And I click on the "Pages" button diff --git a/features/search.feature b/features/search.feature index a9234c1a611..3cd52810e59 100644 --- a/features/search.feature +++ b/features/search.feature @@ -65,3 +65,25 @@ Feature: Search And I search for "Wiki content" And I click "Wiki" link Then I should see "test_wiki" link in the search results + + Scenario: I logout and should see project I am looking for + Given project "Shop" is public + And I logout + And I search for "Sho" + Then I should see "Shop" project link + + Scenario: I logout and should see issues I am looking for + Given project "Shop" is public + And I logout + And project has issues + When I search for "Foo" + And I click "Issues" link + Then I should see "Foo" link in the search results + And I should not see "Bar" link in the search results + + Scenario: I logout and should see project code I am looking for + Given project "Shop" is public + And I logout + When I visit project "Shop" page + And I search for "rspec" on project page + Then I should see code results for project "Shop" diff --git a/features/steps/admin/appearance.rb b/features/steps/admin/appearance.rb new file mode 100644 index 00000000000..0d1be46d11d --- /dev/null +++ b/features/steps/admin/appearance.rb @@ -0,0 +1,72 @@ +class Spinach::Features::AdminAppearance < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + + step 'submit form with new appearance' do + fill_in 'appearance_title', with: 'MyCompany' + fill_in 'appearance_description', with: 'dev server' + click_button 'Save' + end + + step 'I should be redirected to admin appearance page' do + expect(current_path).to eq admin_appearances_path + expect(page).to have_content 'Appearance settings' + end + + step 'I should see newly created appearance' do + expect(page).to have_field('appearance_title', with: 'MyCompany') + expect(page).to have_field('appearance_description', with: 'dev server') + expect(page).to have_content 'Last edit' + end + + step 'I click preview button' do + click_link "Preview" + end + + step 'application has custom appearance' do + create(:appearance) + end + + step 'I should see a customized appearance' do + expect(page).to have_content appearance.title + expect(page).to have_content appearance.description + end + + step 'I attach a logo' do + attach_file(:appearance_logo, Rails.root.join('spec', 'fixtures', 'dk.png')) + click_button 'Save' + end + + step 'I attach header logos' do + attach_file(:appearance_header_logo, Rails.root.join('spec', 'fixtures', 'dk.png')) + click_button 'Save' + end + + step 'I should see a logo' do + expect(page).to have_xpath('//img[@src="/uploads/appearance/logo/1/dk.png"]') + end + + step 'I should see header logos' do + expect(page).to have_xpath('//img[@src="/uploads/appearance/header_logo/1/dk.png"]') + end + + step 'I remove the logo' do + click_link 'Remove logo' + end + + step 'I remove the header logos' do + click_link 'Remove header logo' + end + + step 'I should see logo removed' do + expect(page).not_to have_xpath('//img[@src="/uploads/appearance/logo/1/gitlab_logo.png"]') + end + + step 'I should see header logos removed' do + expect(page).not_to have_xpath('//img[@src="/uploads/appearance/header_logo/1/header_logo_light.png"]') + end + + def appearance + Appearance.last + end +end diff --git a/features/steps/admin/broadcast_messages.rb b/features/steps/admin/broadcast_messages.rb index f6daf852977..af2b4a29313 100644 --- a/features/steps/admin/broadcast_messages.rb +++ b/features/steps/admin/broadcast_messages.rb @@ -1,22 +1,15 @@ class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps include SharedAuthentication include SharedPaths - include SharedAdmin - step 'application already has admin messages' do - FactoryGirl.create(:broadcast_message, message: "Migration to new server") + step 'application already has a broadcast message' do + FactoryGirl.create(:broadcast_message, :expired, message: "Migration to new server") end - step 'I should be all broadcast messages' do + step 'I should see all broadcast messages' do expect(page).to have_content "Migration to new server" end - step 'submit form with new broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - select '2018', from: "broadcast_message_ends_at_1i" - click_button "Add broadcast message" - end - step 'I should be redirected to admin messages page' do expect(current_path).to eq admin_broadcast_messages_path end @@ -26,16 +19,48 @@ class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps end step 'submit form with new customized broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - click_link "Customize colors" + fill_in 'broadcast_message_message', with: 'Application update from **4:00 CST to 5:00 CST**' fill_in 'broadcast_message_color', with: '#f2dede' fill_in 'broadcast_message_font', with: '#b94a48' - select '2018', from: "broadcast_message_ends_at_1i" + select Date.today.next_year.year, from: "broadcast_message_ends_at_1i" click_button "Add broadcast message" end step 'I should see a customized broadcast message' do expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST' + expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST' expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"]) end + + step 'I edit an existing broadcast message' do + click_link 'Edit' + end + + step 'I change the broadcast message text' do + fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW' + click_button 'Update broadcast message' + end + + step 'I should see the updated broadcast message' do + expect(page).to have_content "Application update RIGHT NOW" + end + + step 'I remove an existing broadcast message' do + click_link 'Remove' + end + + step 'I should not see the removed broadcast message' do + expect(page).not_to have_content 'Migration to new server' + end + + step 'I enter a broadcast message with Markdown' do + fill_in 'broadcast_message_message', with: "Live **Markdown** previews. :tada:" + end + + step 'I should see a live preview of the rendered broadcast message' do + page.within('.broadcast-message-preview') do + expect(page).to have_selector('strong', text: 'Markdown') + expect(page).to have_selector('img.emoji') + end + end end diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index 43fd91d0d4c..e1f1db2872f 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -73,6 +73,21 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps end end + step 'group has shared projects' do + share_link = shared_project.project_group_links.new(group_access: Gitlab::Access::MASTER) + share_link.group_id = current_group.id + share_link.save! + end + + step 'I visit group page' do + visit admin_group_path(current_group) + end + + step 'I should see project shared with group' do + expect(page).to have_content(shared_project.name_with_namespace) + expect(page).to have_content "Projects shared with" + end + step 'we have user "John Doe" in group' do current_group.add_reporter(user_john) end @@ -123,6 +138,10 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps @group ||= Group.first end + def shared_project + @shared_project ||= create(:empty_project) + end + def user_john @user_john ||= User.find_by(name: "John Doe") end diff --git a/features/steps/admin/spam_logs.rb b/features/steps/admin/spam_logs.rb new file mode 100644 index 00000000000..ad825fd414c --- /dev/null +++ b/features/steps/admin/spam_logs.rb @@ -0,0 +1,28 @@ +class Spinach::Features::AdminSpamLogs < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + step 'I should see list of spam logs' do + expect(page).to have_content('Spam Logs') + expect(page).to have_content spam_log.source_ip + expect(page).to have_content spam_log.noteable_type + expect(page).to have_content 'N' + expect(page).to have_content spam_log.title + expect(page).to have_content truncate(spam_log.description) + expect(page).to have_link('Remove user') + expect(page).to have_link('Block user') + end + + step 'spam logs exist' do + create(:spam_log) + end + + def spam_log + @spam_log ||= SpamLog.first + end + + def truncate(description) + "#{spam_log.description[0...97]}..." + end +end diff --git a/features/steps/dashboard/archived_projects.rb b/features/steps/dashboard/archived_projects.rb index 36e092f50c6..6510f8d9b32 100644 --- a/features/steps/dashboard/archived_projects.rb +++ b/features/steps/dashboard/archived_projects.rb @@ -19,4 +19,8 @@ class Spinach::Features::DashboardArchivedProjects < Spinach::FeatureSteps step 'I should see "Forum" project link' do expect(page).to have_link "Forum" end + + step 'I click "Show archived projects" link' do + click_link "Show archived projects" + end end diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 63f0ec2b6e8..5062e348844 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -2,6 +2,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject + include SharedIssuable step 'I should see "New Project" link' do expect(page).to have_link "New project" diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb index cbe54e2dc79..f4a56865532 100644 --- a/features/steps/dashboard/issues.rb +++ b/features/steps/dashboard/issues.rb @@ -36,13 +36,17 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps end step 'I click "Authored by me" link' do - select2(current_user.id, from: "#author_id") - select2(nil, from: "#assignee_id") + find("#assignee_id").set("") + find(".js-author-search", match: :first).click + find(".dropdown-menu-author li a", match: :first, text: current_user.to_reference).click end step 'I click "All" link' do - select2(nil, from: "#author_id") - select2(nil, from: "#assignee_id") + find('.js-author-search').click + find('.dropdown-menu-user-full-name', match: :first).click + + find('.js-assignee-search').click + find('.dropdown-menu-user-full-name', match: :first).click end def should_see(issue) diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb index 28c8c6b6015..a2adc87f8ef 100644 --- a/features/steps/dashboard/merge_requests.rb +++ b/features/steps/dashboard/merge_requests.rb @@ -40,13 +40,16 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps end step 'I click "Authored by me" link' do - select2(current_user.id, from: "#author_id") - select2(nil, from: "#assignee_id") + find("#assignee_id").set("") + find(".js-author-search", match: :first).click + find(".dropdown-menu-author li a", match: :first, text: current_user.to_reference).click end step 'I click "All" link' do - select2(nil, from: "#author_id") - select2(nil, from: "#assignee_id") + find(".js-author-search").click + find(".dropdown-menu-author li a", match: :first).click + find(".js-assignee-search").click + find(".dropdown-menu-assignee li a", match: :first).click end def should_see(merge_request) diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb new file mode 100644 index 00000000000..963e4f21365 --- /dev/null +++ b/features/steps/dashboard/todos.rb @@ -0,0 +1,127 @@ +class Spinach::Features::DashboardTodos < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + include SharedUser + include Select2Helper + + step '"John Doe" is a developer of project "Shop"' do + project.team << [john_doe, :developer] + end + + step 'I am a developer of project "Enterprise"' do + enterprise.team << [current_user, :developer] + end + + step '"Mary Jane" is a developer of project "Shop"' do + project.team << [john_doe, :developer] + end + + step 'I have todos' do + create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED) + create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED) + note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?") + create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note) + create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED) + end + + step 'I should see todos assigned to me' do + expect(page).to have_content 'To do 4' + expect(page).to have_content 'Done 0' + + expect(page).to have_link project.name_with_namespace + should_see_todo(1, "John Doe assigned you merge request !#{merge_request.iid}", merge_request.title) + should_see_todo(2, "John Doe mentioned you on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?") + should_see_todo(3, "John Doe assigned you issue ##{issue.iid}", issue.title) + should_see_todo(4, "Mary Jane mentioned you on issue ##{issue.iid}", issue.title) + end + + step 'I mark the todo as done' do + page.within('.todo:nth-child(1)') do + click_link 'Done' + end + + expect(page).to have_content 'To do 3' + expect(page).to have_content 'Done 1' + should_not_see_todo "John Doe assigned you merge request !#{merge_request.iid}" + end + + step 'I click on the "Done" tab' do + click_link 'Done 1' + end + + step 'I should see all todos marked as done' do + expect(page).to have_link project.name_with_namespace + should_see_todo(1, "John Doe assigned you merge request !#{merge_request.iid}", merge_request.title, false) + end + + step 'I filter by "Enterprise"' do + select2(enterprise.id, from: "#project_id") + end + + step 'I filter by "John Doe"' do + select2(john_doe.id, from: "#author_id") + end + + step 'I filter by "Issue"' do + select2('Issue', from: "#type") + end + + step 'I filter by "Mentioned"' do + select2("#{Todo::MENTIONED}", from: '#action_id') + end + + step 'I should not see todos' do + expect(page).to have_content "You're all done!" + end + + step 'I should not see todos related to "Mary Jane" in the list' do + should_not_see_todo "Mary Jane mentioned you on issue ##{issue.iid}" + end + + step 'I should not see todos related to "Merge Requests" in the list' do + should_not_see_todo "John Doe assigned you merge request !#{merge_request.iid}" + end + + step 'I should not see todos related to "Assignments" in the list' do + should_not_see_todo "John Doe assigned you merge request !#{merge_request.iid}" + should_not_see_todo "John Doe assigned you issue ##{issue.iid}" + end + + def should_see_todo(position, title, body, pending = true) + page.within(".todo:nth-child(#{position})") do + expect(page).to have_content title + expect(page).to have_content body + + if pending + expect(page).to have_link 'Done' + else + expect(page).to_not have_link 'Done' + end + end + end + + def should_not_see_todo(title) + expect(page).not_to have_content title + end + + def john_doe + @john_doe ||= user_exists("John Doe", { username: "john_doe" }) + end + + def mary_jane + @mary_jane ||= user_exists("Mary Jane", { username: "mary_jane" }) + end + + def enterprise + @enterprise ||= Project.find_by(name: 'Enterprise') + end + + def issue + @issue ||= create(:issue, assignee: current_user, project: project) + end + + def merge_request + @merge_request ||= create(:merge_request, assignee: current_user, source_project: project) + end +end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 742ba5d71f6..cb6fa8a47da 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -18,7 +18,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I should see empty public project details' do - expect(page).to have_content 'Git global setup' + expect(page).not_to have_content 'Git global setup' end step 'I should see empty public project details with http clone info' do diff --git a/features/steps/group/milestones.rb b/features/steps/group/milestones.rb index 6e57b16ccb6..a167d259837 100644 --- a/features/steps/group/milestones.rb +++ b/features/steps/group/milestones.rb @@ -24,16 +24,19 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps end step 'I click on one group milestone' do + milestones = Milestone.where(title: 'GL-113') + @global_milestone = GlobalMilestone.new('GL-113', milestones) + click_link 'GL-113' end step 'I should see group milestone with descriptions and expiry date' do - expect(page).to have_content('expires at Aug 20, 2114') + expect(page).to have_content('expires on Aug 20, 2114') end step 'I should see group milestone with all issues and MRs assigned to that milestone' do expect(page).to have_content('Milestone GL-113') - expect(page).to have_content('Progress: 0 closed – 3 open') + expect(page).to have_content('3 issues: 3 open and 0 closed') issue = Milestone.find_by(name: 'GL-113').issues.first expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue)) end @@ -60,6 +63,39 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps end end + step 'I should see the "bug" label' do + page.within('#tab-issues') do + expect(page).to have_content 'bug' + end + end + + step 'I should see the "feature" label' do + page.within('#tab-issues') do + expect(page).to have_content 'bug' + end + end + + step 'I should see the project name in the Issue row' do + page.within('#tab-issues') do + @global_milestone.projects.each do |project| + expect(page).to have_content project.name + end + end + end + + step 'I click on the "Labels" tab' do + page.within('.nav-links') do + page.find(:xpath, "//a[@href='#tab-labels']").click + end + end + + step 'I should see the list of labels' do + page.within('#tab-labels') do + expect(page).to have_content 'bug' + expect(page).to have_content 'feature' + end + end + private def group_milestone @@ -68,6 +104,10 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps %w(gitlabhq gitlab-ci cookbook-gitlab).each do |path| project = create :project, path: path, group: group milestone = create :milestone, title: "Version 7.2", project: project + + create(:label, project: project, title: 'bug') + create(:label, project: project, title: 'feature') + create :issue, project: project, assignee: current_user, @@ -80,11 +120,14 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps due_date: '2114-08-20', description: 'Lorem Ipsum is simply dummy text' - create :issue, + issue = create :issue, project: project, assignee: current_user, author: current_user, milestone: milestone + + issue.labels << project.labels.find_by(title: 'bug') + issue.labels << project.labels.find_by(title: 'feature') end end end diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 4c5122d1b7d..e5b7db4c5e3 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -35,7 +35,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see projects activity feed' do - expect(page).to have_content 'closed issue' + expect(page).to have_content 'joined project' end step 'I should see issues from group "Owned" assigned to me' do @@ -44,6 +44,18 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end end + step 'I should not see issues from the archived project' do + @archived_project.issues.each do |issue| + expect(page).not_to have_content issue.title + end + end + + step 'I should not see merge requests from the archived project' do + @archived_project.merge_requests.each do |mr| + expect(page).not_to have_content mr.title + end + end + step 'I should see merge requests from group "Owned" assigned to me' do assigned_to_me(:merge_requests).each do |issue| expect(page).to have_content issue.title[0..80] @@ -113,13 +125,32 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'Group "Owned" has archived project' do group = Group.find_by(name: 'Owned') - create(:project, namespace: group, archived: true, path: "archived-project") + @archived_project = create(:project, namespace: group, archived: true, path: "archived-project") end step 'I should see "archived" label' do expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived') end + step 'I visit group "NonExistentGroup" page' do + visit group_path(-1) + end + + step 'the archived project have some issues' do + create :issue, + project: @archived_project, + assignee: current_user, + author: current_user + end + + step 'the archived project have some merge requests' do + create :merge_request, + source_project: @archived_project, + target_project: @archived_project, + assignee: current_user, + author: current_user + end + private def assigned_to_me(key) diff --git a/features/steps/login_form.rb b/features/steps/login_form.rb deleted file mode 100644 index b9ff6ae67fd..00000000000 --- a/features/steps/login_form.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Spinach::Features::LoginForm < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - include SharedUser - include SharedSearch - - step 'Crowd integration enabled' do - @providers_orig = Gitlab::OAuth::Provider.providers - @omniauth_conf_orig = Gitlab.config.omniauth.enabled - expect(Gitlab::OAuth::Provider).to receive(:providers).and_return([:crowd]) - allow_any_instance_of(ApplicationHelper).to receive(:user_omniauth_authorize_path).and_return(root_path) - expect(Gitlab.config.omniauth).to receive(:enabled).and_return(true) - end - - step 'I should see Crowd login form' do - expect(page).to have_selector '#tab-crowd form' - Gitlab::OAuth::Provider.stub(:providers).and_return(@providers_orig) - Gitlab.config.omniauth.stub(:enabled).and_return(@omniauth_conf_orig) - end - - step 'I visit sign in page' do - visit new_user_session_path - end -end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 0305f7e6da0..909de31a479 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -13,7 +13,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps fill_in 'user_website_url', with: 'testurl' fill_in 'user_location', with: 'Ukraine' fill_in 'user_bio', with: 'I <3 GitLab' - click_button 'Save changes' + click_button 'Update profile settings' @user.reload end @@ -28,7 +28,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps step 'I change my avatar' do attach_file(:user_avatar, File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')) - click_button "Save changes" + click_button "Update profile settings" @user.reload end @@ -43,7 +43,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps step 'I have an avatar' do attach_file(:user_avatar, File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')) - click_button "Save changes" + click_button "Update profile settings" @user.reload end @@ -68,7 +68,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps page.within '.update-password' do fill_in "user_password", with: "22233344" fill_in "user_password_confirmation", with: "22233344" - click_button "Save" + click_button "Save password" end end @@ -77,7 +77,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps fill_in "user_current_password", with: "12345678" fill_in "user_password", with: "22233344" fill_in "user_password_confirmation", with: "22233344" - click_button "Save" + click_button "Save password" end end @@ -86,7 +86,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps fill_in "user_current_password", with: "12345678" fill_in "user_password", with: "password" fill_in "user_password_confirmation", with: "confirmation" - click_button "Save" + click_button "Save password" end end @@ -97,15 +97,15 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I should see a password error message" do - page.within '.alert' do + page.within '.alert-danger' do expect(page).to have_content "Password confirmation doesn't match" end end step 'I reset my token' do - page.within '.update-token' do + page.within '.private-token' do @old_token = @user.private_token - click_button "Reset" + click_button "Reset private token" end end @@ -184,18 +184,14 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end end - step 'I click on new application button' do - click_on 'New Application' - end - step 'I should see application form' do - expect(page).to have_content "New Application" + expect(page).to have_content "Add new application" end step 'I fill application form out and submit' do fill_in :doorkeeper_application_name, with: 'test' fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com' - click_on "Submit" + click_on "Save application" end step 'I see application' do @@ -215,7 +211,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps step 'I change name of application and submit' do expect(page).to have_content "Edit application" fill_in :doorkeeper_application_name, with: 'test_changed' - click_on "Submit" + click_on "Save application" end step 'I see that application was changed' do diff --git a/features/steps/profile/ssh_keys.rb b/features/steps/profile/ssh_keys.rb index c7f879d247d..a400488a532 100644 --- a/features/steps/profile/ssh_keys.rb +++ b/features/steps/profile/ssh_keys.rb @@ -7,8 +7,8 @@ class Spinach::Features::ProfileSshKeys < Spinach::FeatureSteps end end - step 'I click link "Add new"' do - click_link "Add SSH Key" + step 'I should see new ssh key form' do + expect(page).to have_content("Add an SSH key") end step 'I submit new ssh key "Laptop"' do diff --git a/features/steps/project/active_tab.rb b/features/steps/project/active_tab.rb index 9e96fa5ba49..19d81453d8c 100644 --- a/features/steps/project/active_tab.rb +++ b/features/steps/project/active_tab.rb @@ -26,7 +26,7 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps end step 'I click the "Hooks" tab' do - click_link('Web Hooks') + click_link('Webhooks') end step 'I click the "Deploy Keys" tab' do @@ -42,7 +42,7 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps end step 'the active sub nav should be Hooks' do - ensure_active_sub_nav('Web Hooks') + ensure_active_sub_nav('Webhooks') end step 'the active sub nav should be Deploy Keys' do diff --git a/features/steps/project/badges/build.rb b/features/steps/project/badges/build.rb new file mode 100644 index 00000000000..66a48a176e5 --- /dev/null +++ b/features/steps/project/badges/build.rb @@ -0,0 +1,32 @@ +class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedBuilds + include RepoHelpers + + step 'I display builds badge for a master branch' do + visit build_namespace_project_badges_path(@project.namespace, @project, ref: :master, format: :svg) + end + + step 'I should see a build success badge' do + expect_badge('success') + end + + step 'I should see a build failed badge' do + expect_badge('failed') + end + + step 'I should see a build running badge' do + expect_badge('running') + end + + step 'I should see a badge that has not been cached' do + expect(page.response_headers['Cache-Control']).to include 'no-cache' + end + + def expect_badge(status) + svg = Nokogiri::XML.parse(page.body) + expect(page.response_headers).to include('Content-Type' => 'image/svg+xml') + expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy + end +end diff --git a/features/steps/project/builds/artifacts.rb b/features/steps/project/builds/artifacts.rb new file mode 100644 index 00000000000..1bdb57af9d1 --- /dev/null +++ b/features/steps/project/builds/artifacts.rb @@ -0,0 +1,86 @@ +class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedBuilds + include RepoHelpers + + step 'I click artifacts download button' do + page.within('.artifacts') { click_link 'Download' } + end + + step 'I click artifacts browse button' do + page.within('.artifacts') { click_link 'Browse' } + end + + step 'I should see content of artifacts archive' do + page.within('.tree-table') do + expect(page).to have_no_content '..' + expect(page).to have_content 'other_artifacts_0.1.2' + expect(page).to have_content 'ci_artifacts.txt' + expect(page).to have_content 'rails_sample.jpg' + end + end + + step 'I click link to subdirectory within build artifacts' do + page.within('.tree-table') { click_link 'other_artifacts_0.1.2' } + end + + step 'I should see content of subdirectory within artifacts archive' do + page.within('.tree-table') do + expect(page).to have_content '..' + expect(page).to have_content 'another-subdirectory' + expect(page).to have_content 'doc_sample.txt' + end + end + + step 'recent build artifacts contain directory with UTF-8 characters' do + # metadata fixture contains relevant directory + end + + step 'I navigate to directory with UTF-8 characters in name' do + page.within('.tree-table') { click_link 'tests_encoding' } + page.within('.tree-table') { click_link 'utf8 test dir ✓' } + end + + step 'I should see content of directory with UTF-8 characters in name' do + page.within('.tree-table') do + expect(page).to have_content '..' + expect(page).to have_content 'regular_file_2' + end + end + + step 'recent build artifacts contain directory with invalid UTF-8 characters' do + # metadata fixture contains relevant directory + end + + step 'I navigate to parent directory of directory with invalid name' do + page.within('.tree-table') { click_link 'tests_encoding' } + end + + step 'I should not see directory with invalid name on the list' do + page.within('.tree-table') do + expect(page).to have_no_content('non-utf8-dir') + end + end + + step 'I click a link to file within build artifacts' do + page.within('.tree-table') { find_link('ci_artifacts.txt').click } + end + + step 'download of a file extracted from build artifacts should start' do + # this will be accelerated by Workhorse + response_json = JSON.parse(page.body, symbolize_names: true) + expect(response_json[:archive]).to end_with('build_artifacts.zip') + expect(response_json[:entry]).to eq Base64.encode64('ci_artifacts.txt') + end + + step 'I click a first row within build artifacts table' do + row = first('tr[data-link]') + @row_path = row['data-link'] + row.click + end + + step 'page with a coresponding path is loading' do + expect(current_path).to eq @row_path + end +end diff --git a/features/steps/project/builds/permissions.rb b/features/steps/project/builds/permissions.rb new file mode 100644 index 00000000000..6e9d6504fd5 --- /dev/null +++ b/features/steps/project/builds/permissions.rb @@ -0,0 +1,7 @@ +class Spinach::Features::ProjectBuildsPermissions < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedBuilds + include SharedPaths + include RepoHelpers +end diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb new file mode 100644 index 00000000000..e9e2359146e --- /dev/null +++ b/features/steps/project/builds/summary.rb @@ -0,0 +1,39 @@ +class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedBuilds + include RepoHelpers + + step 'I see coverage' do + page.within('td.coverage') do + expect(page).to have_content "99.9%" + end + end + + step 'I see button to CI Lint' do + page.within('.nav-controls') do + ci_lint_tool_link = page.find_link('CI Lint') + expect(ci_lint_tool_link[:href]).to eq ci_lint_path + end + end + + step 'I click erase build button' do + click_link 'Erase' + end + + step 'recent build has been erased' do + expect(@build.artifacts_file.exists?).to be_falsy + expect(@build.artifacts_metadata.exists?).to be_falsy + expect(@build.trace).to be_empty + end + + step 'recent build summary does not have artifacts widget' do + expect(page).to have_no_css('.artifacts') + end + + step 'recent build summary contains information saying that build has been erased' do + page.within('.erased') do + expect(page).to have_content 'Build has been erased' + end + end +end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index a3141fe3be1..93c37bf507f 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -33,6 +33,13 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps expect(page).to have_content "Showing #{sample_commit.files_changed_count} changed files" end + step 'I fill compare fields with branches' do + fill_in 'from', with: 'feature' + fill_in 'to', with: 'master' + + click_button 'Compare' + end + step 'I fill compare fields with refs' do fill_in "from", with: sample_commit.parent_id fill_in "to", with: sample_commit.id @@ -56,6 +63,56 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps expect(page).to have_content "Showing 2 changed files" end + step 'I visit commits list page for feature branch' do + visit namespace_project_commits_path(@project.namespace, @project, 'feature', { limit: 5 }) + end + + step 'I see feature branch commits' do + commit = @project.repository.commit('0b4bc9a') + expect(page).to have_content(@project.name) + expect(page).to have_content(commit.message[0..12]) + expect(page).to have_content(commit.short_id) + end + + step 'project have an open merge request' do + create(:merge_request, + title: 'Feature', + source_project: @project, + source_branch: 'feature', + target_branch: 'master', + author: @project.users.first + ) + end + + step 'I click the "Compare" tab' do + click_link('Compare') + end + + step 'I fill compare fields with branches' do + fill_in 'from', with: 'master' + fill_in 'to', with: 'feature' + + click_button 'Compare' + end + + step 'I see compared branches' do + expect(page).to have_content 'Commits (1)' + expect(page).to have_content 'Showing 1 changed file with 5 additions and 0 deletions' + end + + step 'I see button to create a new merge request' do + expect(page).to have_link 'Create Merge Request' + end + + step 'I should not see button to create a new merge request' do + expect(page).to_not have_link 'Create Merge Request' + end + + step 'I should see button to the merge request' do + merge_request = MergeRequest.find_by(title: 'Feature') + expect(page).to have_link "View Open Merge Request", href: namespace_project_merge_request_path(@project.namespace, @project, merge_request) + end + step 'I see breadcrumb links' do expect(page).to have_selector('ul.breadcrumb') expect(page).to have_selector('ul.breadcrumb a', count: 4) @@ -69,8 +126,11 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I visit big commit page' do - stub_const('Commit::DIFF_SAFE_FILES', 20) - visit namespace_project_commit_path(@project.namespace, @project, sample_big_commit.id) + # Create a temporary scope to ensure that the stub_const is removed after user + RSpec::Mocks.with_temporary_scope do + stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_lines: 1, max_files: 1 }) + visit namespace_project_commit_path(@project.namespace, @project, sample_big_commit.id) + end end step 'I see big commit warning' do @@ -124,4 +184,13 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps expect(page).to have_content "build: pending" expect(page).to have_content "1 build" end + + step 'I search "submodules" commits' do + fill_in 'commits-search', with: 'submodules' + end + + step 'I should see only "submodules" commits' do + expect(page).to have_content "More submodules" + expect(page).not_to have_content "Change some files" + end end diff --git a/features/steps/project/commits/revert.rb b/features/steps/project/commits/revert.rb new file mode 100644 index 00000000000..94a5d4e2e4d --- /dev/null +++ b/features/steps/project/commits/revert.rb @@ -0,0 +1,40 @@ +class Spinach::Features::RevertCommits < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include SharedDiffNote + include RepoHelpers + + step 'I click on commit link' do + visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) + end + + step 'I click on the revert button' do + find("a[href='#modal-revert-commit']").click + end + + step 'I revert the changes directly' do + page.within('#modal-revert-commit') do + uncheck 'create_merge_request' + click_button 'Revert' + end + end + + step 'I should see the revert commit notice' do + page.should have_content('The commit has been successfully reverted.') + end + + step 'I should see a revert error' do + page.should have_content('Sorry, we cannot revert this commit automatically.') + end + + step 'I revert the changes in a new merge request' do + page.within('#modal-revert-commit') do + click_button 'Revert' + end + end + + step 'I should see the new merge request notice' do + page.should have_content('The commit has been successfully reverted. You can now submit a merge request to get this change into the original branch.') + end +end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index b0230add34f..527f7853da9 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -30,4 +30,54 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps click_link current_user.name end end + + step 'I should see "New merge request"' do + expect(page).to have_content(/new merge request/i) + end + + step 'I goto the Merge Requests page' do + page.within '.page-sidebar-expanded' do + click_link "Merge Requests" + end + end + + step 'I click link "New merge request"' do + expect(page).to have_content(/new merge request/i) + click_link "New Merge Request" + end + + step 'I should see the new merge request page for my namespace' do + current_path.should have_content(/#{current_user.namespace.name}/i) + end + + step 'I visit the forks page of the "Shop" project' do + @project = Project.where(name: 'Shop').last + visit namespace_project_forks_path(@project.namespace, @project) + end + + step 'I should see my fork on the list' do + page.within('.projects-list-holder') do + project = @user.fork_of(@project) + expect(page).to have_content("#{project.namespace.human_name} / #{project.name}") + end + end + + step 'I make forked repo invalid' do + project = @user.fork_of(@project) + project.path = 'test-crappy-path' + project.save! + end + + step 'There is an existent fork of the "Shop" project' do + user = create(:user, name: 'Mike') + @forked_project = Projects::ForkService.new(@project, user).execute + end + + step 'I should not see the other fork listed' do + expect(page).not_to have_content("#{@forked_project.namespace.human_name} / #{@forked_project.name}") + end + + step 'I should see a private fork notice' do + expect(page).to have_content("1 private fork") + end end diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb index cbdce78dc0c..7e4425ff662 100644 --- a/features/steps/project/forked_merge_requests.rb +++ b/features/steps/project/forked_merge_requests.rb @@ -43,7 +43,9 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps expect(page).to have_css("h3.page-title", text: "New Merge Request") - fill_in "merge_request_title", with: "Merge Request On Forked Project" + page.within 'form#new_merge_request' do + fill_in "merge_request_title", with: "Merge Request On Forked Project" + end end step 'I submit the merge request' do diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb index be4db770948..4994df589a7 100644 --- a/features/steps/project/hooks.rb +++ b/features/steps/project/hooks.rb @@ -25,14 +25,14 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps step 'I submit new hook' do @url = FFaker::Internet.uri("http") fill_in "hook_url", with: @url - expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) + expect { click_button "Add Webhook" }.to change(ProjectHook, :count).by(1) end step 'I submit new hook with SSL verification enabled' do @url = FFaker::Internet.uri("http") fill_in "hook_url", with: @url check "hook_enable_ssl_verification" - expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) + expect { click_button "Add Webhook" }.to change(ProjectHook, :count).by(1) end step 'I should see newly created hook' do diff --git a/features/steps/project/issues/award_emoji.rb b/features/steps/project/issues/award_emoji.rb index 2c2ed08655e..c5d45709b44 100644 --- a/features/steps/project/issues/award_emoji.rb +++ b/features/steps/project/issues/award_emoji.rb @@ -8,24 +8,32 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps visit namespace_project_issue_path(@project.namespace, @project, @issue) end + step 'I click the thumbsup award Emoji' do + page.within '.awards' do + thumbsup = page.first('.award-control') + thumbsup.click + thumbsup.hover + end + end + step 'I click to emoji-picker' do - page.within '.awards-controls' do - page.find('.add-award').click + page.within '.awards' do + page.find('.js-add-award').click end end step 'I click to emoji in the picker' do page.within '.emoji-menu-content' do - page.first('.emoji-icon').click + page.first('.js-emoji-btn').click end end step 'I can remove it by clicking to icon' do page.within '.awards' do expect do - page.find('.award.active').click + page.find('.js-emoji-btn.active').click sleep 0.3 - end.to change{ page.all(".award").size }.from(3).to(2) + end.to change{ page.all(".award-control.js-emoji-btn").size }.from(3).to(2) end end @@ -38,8 +46,25 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps step 'I have award added' do page.within '.awards' do - expect(page).to have_selector '.award' - expect(page.find('.award.active .counter')).to have_content '1' + expect(page).to have_selector '.js-emoji-btn' + expect(page.find('.js-emoji-btn.active .js-counter')).to have_content '1' + expect(page).to have_css(".js-emoji-btn.active[data-original-title='me']") + end + end + + step 'I have no awards added' do + page.within '.awards' do + expect(page).to have_selector '.award-control.js-emoji-btn' + expect(page.all('.award-control.js-emoji-btn').size).to eq(2) + + # Check tooltip data + page.all('.award-control.js-emoji-btn').each do |element| + expect(element['title']).to eq("") + end + + page.all('.award-control .js-counter').each do |element| + expect(element).to have_content '0' + end end end @@ -51,7 +76,7 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps step 'I leave comment with a single emoji' do page.within('.js-main-target-form') do fill_in 'note[note]', with: ':smile:' - click_button 'Add Comment' + click_button 'Comment' end end @@ -66,4 +91,13 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps expect(page).to have_selector '[data-emoji="raised_hand"]' end end + + step 'The emoji menu is visible' do + page.find(".emoji-menu.is-visible") + end + + step 'The search field is focused' do + expect(page).to have_selector('#emoji_search') + expect(page.evaluate_script('document.activeElement.id')).to eq('emoji_search') + end end diff --git a/features/steps/project/issues/filter_labels.rb b/features/steps/project/issues/filter_labels.rb index 50bb32429b9..6d50501a722 100644 --- a/features/steps/project/issues/filter_labels.rb +++ b/features/steps/project/issues/filter_labels.rb @@ -29,7 +29,10 @@ class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps end step 'I click link "bug"' do - select2('bug', from: "#label_name") + page.find('.js-label-select').click + sleep 0.5 + execute_script("$('.dropdown-menu-labels li:contains(\"bug\") a').click()") + sleep 2 end step 'I click link "feature"' do diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index 8e8c9c57452..8c31fa890b2 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -27,7 +27,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I click link "Closed"' do - click_link "Closed" + find('.issues-state-filters a', text: "Closed").click end step 'I click button "Unsubscribe"' do @@ -54,19 +54,24 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps 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 click_link "New Issue" end step 'I click "author" dropdown' do - first('#s2id_author_id').click + page.find('.js-author-search').click + sleep 1 end step 'I see current user as the first user' do - expect(page).to have_selector('.user-result', visible: true, count: 3) - users = page.all('.user-name') + expect(page).to have_selector('.dropdown-content', visible: true) + users = page.all('.dropdown-menu-author .dropdown-content li a') expect(users[0].text).to eq 'Any Author' - expect(users[1].text).to eq current_user.name + expect(users[1].text).to eq "#{current_user.name} #{current_user.to_reference}" end step 'I submit new issue "500 error on profile"' do @@ -170,6 +175,13 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps 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", @@ -177,6 +189,56 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps author: project.users.first) end + step 'issue "Release 0.4" have 2 upvotes and 1 downvote' do + issue = Issue.find_by(title: 'Release 0.4') + create_list(:upvote_note, 2, project: project, noteable: issue) + create(:downvote_note, project: project, noteable: issue) + end + + step 'issue "Tweet control" have 1 upvote and 2 downvotes' do + issue = Issue.find_by(title: 'Tweet control') + create(:upvote_note, project: project, noteable: issue) + create_list(:downvote_note, 2, project: project, noteable: issue) + end + + step 'The list should be sorted by "Least popular"' do + page.within '.issues-list' do + page.within 'li.issue:nth-child(1)' do + expect(page).to have_content 'Tweet control' + expect(page).to have_content '1 2' + end + + page.within 'li.issue:nth-child(2)' do + expect(page).to have_content 'Release 0.4' + expect(page).to have_content '2 1' + end + + page.within 'li.issue:nth-child(3)' do + expect(page).to have_content 'Bugfix' + expect(page).to_not have_content '0 0' + end + end + end + + step 'The list should be sorted by "Most popular"' 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).to_not have_content '0 0' + end + end + end + step 'empty project "Empty Project"' do create :empty_project, name: 'Empty Project', namespace: @user.namespace end @@ -206,7 +268,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps 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 "Add Comment" + click_button "Comment" sleep 0.05 end end @@ -293,7 +355,9 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps expect(page).to have_content('Yay!') end end + def filter_issue(text) fill_in 'issue_search', with: text end + end diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index e2eda511497..4faa0f4707c 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -59,7 +59,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I should see 3 issues' do - expect(page).to have_selector('#tab-issues li.issue-row', count: 4) + expect(page).to have_selector('#tab-issues li.issuable-row', count: 4) end step 'I click link to remove milestone' do diff --git a/features/steps/project/issues/references.rb b/features/steps/project/issues/references.rb new file mode 100644 index 00000000000..69e8b5cbde5 --- /dev/null +++ b/features/steps/project/issues/references.rb @@ -0,0 +1,7 @@ +class Spinach::Features::ProjectIssuesReferences < Spinach::FeatureSteps + include SharedAuthentication + include SharedIssuable + include SharedNote + include SharedProject + include SharedUser +end diff --git a/features/steps/project/labels.rb b/features/steps/project/labels.rb new file mode 100644 index 00000000000..17944527e3a --- /dev/null +++ b/features/steps/project/labels.rb @@ -0,0 +1,34 @@ +class Spinach::Features::Labels < Spinach::FeatureSteps + include SharedAuthentication + include SharedIssuable + include SharedProject + include SharedNote + include SharedPaths + include SharedMarkdown + + step 'And I visit project "Shop" labels page' do + visit namespace_project_labels_path(project.namespace, project) + end + + step 'I should see that I am subscribed to the "bug" label' do + expect(subscribe_button).to have_content 'Unsubscribe' + end + + step 'I should see that I am not subscribed to the "bug" label' do + expect(subscribe_button).to have_content 'Subscribe' + end + + step 'I click button "Unsubscribe" for the "bug" label' do + subscribe_button.click + end + + step 'I click button "Subscribe" for the "bug" label' do + subscribe_button.click + end + + private + + def subscribe_button + first('.subscribe-button span') + end +end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index be993d11093..91fe19dd477 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -16,10 +16,18 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps click_link "Bug NS-04" end + step 'I click link "Feature NS-05"' do + click_link "Feature NS-05" + end + step 'I click link "All"' do click_link "All" end + step 'I click link "Merged"' do + click_link "Merged" + end + step 'I click link "Closed"' do click_link "Closed" end @@ -40,8 +48,12 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps expect(page).to have_content "Bug NS-04" end + step 'I should see merge request "Feature NS-05"' do + expect(page).to have_content "Feature NS-05" + end + step 'I should not see "master" branch' do - expect(page).not_to have_content "master" + expect(find('.merge-request-info')).not_to have_content "master" end step 'I should see "other_branch" branch' do @@ -60,7 +72,6 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps expect(page).not_to have_content "Feature NS-03" end - step 'I should not see "Bug NS-04" in merge requests' do expect(page).not_to have_content "Bug NS-04" end @@ -121,6 +132,30 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps author: project.users.first) end + step 'project "Shop" have "Feature NS-05" merged merge request' do + create(:merged_merge_request, + title: "Feature NS-05", + source_project: project, + target_project: project, + author: project.users.first) + end + + step 'project "Shop" have "Bug NS-07" open merge request with rebased branch' do + create(:merge_request, :rebased, + title: "Bug NS-07", + source_project: project, + target_project: project, + author: project.users.first) + end + + step 'project "Shop" have "Bug NS-08" open merge request with diverged branch' do + create(:merge_request, :diverged, + title: "Bug NS-08", + source_project: project, + target_project: project, + author: project.users.first) + end + step 'project "Shop" have "Feature NS-03" closed merge request' do create(:closed_merge_request, title: "Feature NS-03", @@ -138,6 +173,56 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps author: project.users.first) end + step 'merge request "Bug NS-04" have 2 upvotes and 1 downvote' do + merge_request = MergeRequest.find_by(title: 'Bug NS-04') + create_list(:upvote_note, 2, project: project, noteable: merge_request) + create(:downvote_note, project: project, noteable: merge_request) + end + + step 'merge request "Bug NS-06" have 1 upvote and 2 downvotes' do + merge_request = MergeRequest.find_by(title: 'Bug NS-06') + create(:upvote_note, project: project, noteable: merge_request) + create_list(:downvote_note, 2, project: project, noteable: merge_request) + end + + step 'The list should be sorted by "Least popular"' do + page.within '.mr-list' do + page.within 'li.merge-request:nth-child(1)' do + expect(page).to have_content 'Bug NS-06' + expect(page).to have_content '1 2' + end + + page.within 'li.merge-request:nth-child(2)' do + expect(page).to have_content 'Bug NS-04' + expect(page).to have_content '2 1' + end + + page.within 'li.merge-request:nth-child(3)' do + expect(page).to have_content 'Bug NS-05' + expect(page).to_not have_content '0 0' + end + end + end + + step 'The list should be sorted by "Most popular"' do + page.within '.mr-list' do + page.within 'li.merge-request:nth-child(1)' do + expect(page).to have_content 'Bug NS-04' + expect(page).to have_content '2 1' + end + + page.within 'li.merge-request:nth-child(2)' do + expect(page).to have_content 'Bug NS-06' + expect(page).to have_content '1 2' + end + + page.within 'li.merge-request:nth-child(3)' do + expect(page).to have_content 'Bug NS-05' + expect(page).to_not have_content '0 0' + end + end + end + step 'I click on the Changes tab' do page.within '.merge-request-tabs' do click_link 'Changes' @@ -181,6 +266,15 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps leave_comment "Line is wrong" end + step 'user "John Doe" leaves a comment like "Line is wrong" on diff' do + mr = MergeRequest.find_by(title: "Bug NS-05") + create(:note_on_merge_request_diff, project: project, + noteable_id: mr.id, + author: user_exists("John Doe"), + line_code: sample_commit.line_code, + note: 'Line is wrong') + end + step 'I leave a comment like "Line is wrong" on diff in commit' do click_diff_line(sample_commit.line_code) leave_comment "Line is wrong" @@ -238,6 +332,22 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end end + step 'I should see a discussion by user "John Doe" has started on diff' do + page.within(".notes .discussion") do + page.should have_content "#{user_exists("John Doe").name} started a discussion" + page.should have_content sample_commit.line_code_path + page.should have_content "Line is wrong" + end + end + + step 'I should see a badge of "1" next to the discussion link' do + expect_discussion_badge_to_have_counter("1") + end + + step 'I should see a badge of "0" next to the discussion link' do + expect_discussion_badge_to_have_counter("0") + end + step 'I should see a discussion has started on commit diff' do page.within(".notes .discussion") do page.should have_content "#{current_user.name} started a discussion on commit" @@ -329,7 +439,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps page.within(".js-discussion-note-form") do fill_in "note_note", with: "Line is correct" - click_button "Add Comment" + click_button "Comment" end page.within ".files [id^=diff]:nth-child(2) .note-body > .note-text" do @@ -342,7 +452,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps page.within(".js-discussion-note-form") do fill_in "note_note", with: "Line is wrong on here" - click_button "Add Comment" + click_button "Comment" end end @@ -415,6 +525,18 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end end + step 'I should see the diverged commits count' do + page.within ".mr-source-target" do + expect(page).to have_content /([0-9]+ commits behind)/ + end + end + + step 'I should not see the diverged commits count' do + page.within ".mr-source-target" do + expect(page).not_to have_content /([0-9]+ commit[s]? behind)/ + end + end + def merge_request @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") end @@ -426,7 +548,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps def leave_comment(message) page.within(".js-discussion-note-form", visible: true) do fill_in "note_note", with: message - click_button "Add Comment" + click_button "Comment" end page.within(".notes_holder", visible: true) do expect(page).to have_content message @@ -444,4 +566,10 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps def have_visible_content (text) have_css("*", text: text, visible: true) end + + def expect_discussion_badge_to_have_counter(value) + page.within(".notes-tab .badge") do + page.should have_content value + end + end end diff --git a/features/steps/project/merge_requests/acceptance.rb b/features/steps/project/merge_requests/acceptance.rb index 2685f5fd6b4..4fda0731e2f 100644 --- a/features/steps/project/merge_requests/acceptance.rb +++ b/features/steps/project/merge_requests/acceptance.rb @@ -29,7 +29,7 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps step 'There is an open Merge Request' do @user = create(:user) @project = create(:project, :public) - @project_member = create(:project_member, user: @user, project: @project, access_level: ProjectMember::DEVELOPER) + @project_member = create(:project_member, :developer, user: @user, project: @project) @merge_request = create(:merge_request, :with_diffs, :simple, source_project: @project) end diff --git a/features/steps/project/merge_requests/references.rb b/features/steps/project/merge_requests/references.rb new file mode 100644 index 00000000000..ab2ae6847a2 --- /dev/null +++ b/features/steps/project/merge_requests/references.rb @@ -0,0 +1,7 @@ +class Spinach::Features::ProjectMergeRequestsReferences < Spinach::FeatureSteps + include SharedAuthentication + include SharedIssuable + include SharedNote + include SharedProject + include SharedUser +end diff --git a/features/steps/project/merge_requests/revert.rb b/features/steps/project/merge_requests/revert.rb new file mode 100644 index 00000000000..efbc4831ce1 --- /dev/null +++ b/features/steps/project/merge_requests/revert.rb @@ -0,0 +1,56 @@ +class Spinach::Features::RevertMergeRequests < Spinach::FeatureSteps + include LoginHelpers + include GitlabRoutingHelper + + step 'I click on the revert button' do + find("a[href='#modal-revert-commit']").click + end + + step 'I revert the changes directly' do + page.within('#modal-revert-commit') do + uncheck 'create_merge_request' + click_button 'Revert' + end + end + + step 'I should see the revert merge request notice' do + page.should have_content('The merge request has been successfully reverted.') + end + + step 'I should not see the revert button' do + expect(page).not_to have_selector(:xpath, "a[href='#modal-revert-commit']") + end + + step 'I am on the Merge Request detail page' do + visit merge_request_path(@merge_request) + end + + step 'I click on Accept Merge Request' do + click_button('Accept Merge Request') + end + + step 'I am signed in as a developer of the project' do + login_as(@user) + end + + step 'There is an open Merge Request' do + @user = create(:user) + @project = create(:project, :public) + @project_member = create(:project_member, :developer, user: @user, project: @project) + @merge_request = create(:merge_request, :with_diffs, :simple, source_project: @project) + end + + step 'I should see a revert error' do + page.should have_content('Sorry, we cannot revert this merge request automatically.') + end + + step 'I revert the changes in a new merge request' do + page.within('#modal-revert-commit') do + click_button 'Revert' + end + end + + step 'I should see the new merge request notice' do + page.should have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.') + end +end diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index 7a83d32a240..9b59b682676 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -41,17 +41,14 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps When 'I switch ref to "feature"' do select 'feature', from: 'ref' - sleep 2 end When 'I switch ref to "v1.0.0"' do select 'v1.0.0', from: 'ref' - sleep 2 end When 'click "Show only selected branch" checkbox' do find('#filter_ref').click - sleep 2 end step 'page should have content not containing "v1.0.0"' do @@ -60,7 +57,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end end - step 'page should not have content not containing "v1.0.0"' do + step 'page should have "v1.0.0" in title' do + expect(page).to have_css 'title', text: 'Network · v1.0.0', visible: false + end + + step 'page should only have content from "v1.0.0"' do page.within '.network-graph' do expect(page).not_to have_content 'Change some files' end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 37bf52b4a95..ef185861e00 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -144,4 +144,14 @@ class Spinach::Features::Project < Spinach::FeatureSteps expect(page).to have_content 'Notification settings saved' end end + + step 'I create bare repo' do + click_link 'Create empty bare repository' + end + + step 'I should see command line instructions' do + page.within ".empty_wrapper" do + expect(page).to have_content("Command line instructions") + end + end end diff --git a/features/steps/project/project_find_file.rb b/features/steps/project/project_find_file.rb new file mode 100644 index 00000000000..8c1d09d6cc6 --- /dev/null +++ b/features/steps/project/project_find_file.rb @@ -0,0 +1,73 @@ +class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + include SharedProjectTab + + step 'I press "t"' do + find('body').native.send_key('t') + end + + step 'I click Find File button' do + click_link 'Find File' + end + + step 'I should see "find file" page' do + ensure_active_main_tab('Files') + expect(page).to have_selector('.file-finder-holder', count: 1) + end + + step 'I fill in Find by path with "git"' do + ensure_active_main_tab('Files') + expect(page).to have_selector('.file-finder-holder', count: 1) + end + + step 'I fill in file find with "git"' do + find_file "git" + end + + step 'I fill in file find with "change"' do + find_file "change" + end + + step 'I fill in file find with "asdfghjklqwertyuizxcvbnm"' do + find_file "asdfghjklqwertyuizxcvbnm" + end + + step 'I should see "VERSION" in files' do + expect(page).to have_content("VERSION") + end + + step 'I should not see "VERSION" in files' do + expect(page).not_to have_content("VERSION") + end + + step 'I should see "CHANGELOG" in files' do + expect(page).to have_content("CHANGELOG") + end + + step 'I should not see "CHANGELOG" in files' do + expect(page).not_to have_content("CHANGELOG") + end + + step 'I should see ".gitmodules" in files' do + expect(page).to have_content(".gitmodules") + end + + step 'I should not see ".gitmodules" in files' do + expect(page).not_to have_content(".gitmodules") + end + + step 'I should see ".gitignore" in files' do + expect(page).to have_content(".gitignore") + end + + step 'I should not see ".gitignore" in files' do + expect(page).not_to have_content(".gitignore") + end + + + def find_file(text) + fill_in 'file_find', with: text + end +end diff --git a/features/steps/project/project_group_links.rb b/features/steps/project/project_group_links.rb new file mode 100644 index 00000000000..739a85e5fa4 --- /dev/null +++ b/features/steps/project/project_group_links.rb @@ -0,0 +1,50 @@ +class Spinach::Features::ProjectGroupLinks < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include Select2Helper + + step 'I should see project already shared with group "Ops"' do + page.within '.enabled-groups' do + expect(page).to have_content "Ops" + end + end + + step 'I should see project is not shared with group "Market"' do + page.within '.enabled-groups' do + expect(page).not_to have_content "Market" + end + end + + step 'I select group "Market" for share' do + group = Group.find_by(path: 'market') + select2(group.id, from: "#link_group_id") + select "Master", from: 'link_group_access' + click_button "Share" + end + + step 'I should see project is shared with group "Market"' do + page.within '.enabled-groups' do + expect(page).to have_content "Market" + end + end + + step 'project "Shop" is shared with group "Ops"' do + group = create(:group, name: 'Ops') + share_link = project.project_group_links.new(group_access: Gitlab::Access::MASTER) + share_link.group_id = group.id + share_link.save! + end + + step 'project "Shop" is not shared with group "Market"' do + create(:group, name: 'Market', path: 'market') + end + + step 'I visit project group links page' do + visit namespace_project_group_links_path(project.namespace, project) + end + + def project + @project ||= Project.find_by_name "Shop" + end +end diff --git a/features/steps/project/project_milestone.rb b/features/steps/project/project_milestone.rb new file mode 100644 index 00000000000..2508c09e36d --- /dev/null +++ b/features/steps/project/project_milestone.rb @@ -0,0 +1,59 @@ +class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'milestone has issue "Bugfix1" with labels: "bug", "feature"' do + project = Project.find_by(name: "Shop") + milestone = project.milestones.find_by(title: 'v2.2') + issue = create(:issue, title: "Bugfix1", project: project, milestone: milestone) + issue.labels << project.labels.find_by(title: 'bug') + issue.labels << project.labels.find_by(title: 'feature') + end + + step 'milestone has issue "Bugfix2" with labels: "bug", "enhancement"' do + project = Project.find_by(name: "Shop") + milestone = project.milestones.find_by(title: 'v2.2') + issue = create(:issue, title: "Bugfix2", project: project, milestone: milestone) + issue.labels << project.labels.find_by(title: 'bug') + issue.labels << project.labels.find_by(title: 'enhancement') + end + + step 'project "Shop" has milestone "v2.2"' do + project = Project.find_by(name: "Shop") + milestone = create(:milestone, + title: "v2.2", + project: project, + description: "# Description header" + ) + 3.times { create(:issue, project: project, milestone: milestone) } + end + + step 'I should see the list of labels' do + expect(page).to have_selector('ul.manage-labels-list') + end + + step 'I should see the labels "bug", "enhancement" and "feature"' do + page.within('#tab-issues') do + expect(page).to have_content 'bug' + expect(page).to have_content 'enhancement' + expect(page).to have_content 'feature' + end + end + + step 'I should see the "bug" label listed only once' do + page.within('#tab-labels') do + expect(page).to have_content('bug', count: 1) + end + end + + step 'I click link "v2.2"' do + click_link "v2.2" + end + + step 'I click link "Labels"' do + page.within('.nav-links') do + page.find(:xpath, "//a[@href='#tab-labels']").click + end + end +end diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index 504654f90dd..786a0cad975 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -77,7 +77,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps step 'I leave a comment like "Good snippet!"' do page.within('.js-main-target-form') do fill_in "note_note", with: "Good snippet!" - click_button "Add Comment" + click_button "Comment" end end diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index d08935aa101..243469b8e7d 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -52,7 +52,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I should see raw file content' do - expect(source).to eq sample_blob.data + expect(source).to eq '' # Body is filled in by gitlab-workhorse end step 'I click button "Edit"' do @@ -351,6 +351,19 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps expect(page).to have_content "You're not allowed to make changes to this project directly. A fork of this project has been created that you can make changes in, so you can submit a merge request." end + # SVG files + step 'I upload a new SVG file' do + drop_in_dropzone test_svg_file + end + + step 'I visit the SVG file' do + visit namespace_project_blob_path(@project.namespace, @project, 'new_branch_name/logo_sample.svg') + end + + step 'I can see the new rendered SVG image' do + expect(page).to have_css('.file-content img') + end + private def set_new_content @@ -410,4 +423,8 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps def test_image_file File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') end + + def test_svg_file + File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg') + end end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index 3a4f7a6e01c..2134dae168a 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -238,7 +238,11 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I see new wiki page named test' do expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "test") - expect(page).to have_content "Edit Page test" + + page.within(:css, ".nav-text") do + expect(page).to have_content "Test" + expect(page).to have_content "Edit Page" + end end When 'I go back to wiki page home' do @@ -252,7 +256,11 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I see Gitlab API document' do expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "api") - expect(page).to have_content "Edit Page api" + + page.within(:css, ".nav-text") do + expect(page).to have_content "Edit" + expect(page).to have_content "Api" + end end step 'I click on Rake tasks link' do @@ -261,7 +269,11 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I see Rake tasks directory' do expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "raketasks") - expect(page).to have_content "Edit Page raketasks" + + page.within(:css, ".nav-text") do + expect(page).to have_content "Edit" + expect(page).to have_content "Rake" + end end step 'I go directory which contains README file' do diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index caad52def79..3fbcf770b62 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -123,4 +123,23 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps click_link('Remove user from team') end end + + step 'I share project with group "OpenSource"' do + project = Project.find_by(name: 'Shop') + os_group = create(:group, name: 'OpenSource') + create(:project, group: os_group) + @os_user1 = create(:user) + @os_user2 = create(:user) + os_group.add_owner(@os_user1) + os_group.add_user(@os_user2, Gitlab::Access::DEVELOPER) + share_link = project.project_group_links.new(group_access: Gitlab::Access::MASTER) + share_link.group_id = os_group.id + share_link.save! + end + + step 'I should see "Opensource" group user listing' do + expect(page).to have_content("Shared with OpenSource group, members with Master role (2)") + expect(page).to have_content(@os_user1.name) + expect(page).to have_content(@os_user2.name) + end end diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 91d227fadbf..223b7277b51 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -120,7 +120,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps step 'I should see the new wiki page form' do expect(current_path).to match('wikis/image.jpg') expect(page).to have_content('New Wiki Page') - expect(page).to have_content('Edit Page image.jpg') + expect(page).to have_content('Edit Page') end step 'I create a New page with paths' do @@ -132,16 +132,6 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps expect(current_path).to include 'one/two/three' end - step 'I create a New page with an invalid name' do - click_on 'New Page' - fill_in 'Page slug', with: 'invalid name' - click_on 'Create Page' - end - - step 'I should see an error message' do - expect(page).to have_content "The page slug is invalid" - end - step 'I should see non-escaped link in the pages list' do expect(page).to have_xpath("//a[@href='/#{project.path_with_namespace}/wikis/one/two/three']") end @@ -169,11 +159,13 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see the page history' do - expect(page).to have_content('History for') + page.within(:css, ".nav-text") do + expect(page).to have_content('History') + end end step 'I search for Wiki content' do - fill_in "Search in this project", with: "wiki_content" + fill_in "Search", with: "wiki_content" click_button "Search" end diff --git a/features/steps/search.rb b/features/steps/search.rb index 79273cbad9a..0ad837ebe1d 100644 --- a/features/steps/search.rb +++ b/features/steps/search.rb @@ -18,6 +18,11 @@ class Spinach::Features::Search < Spinach::FeatureSteps click_button "Search" end + step 'I search for "rspec" on project page' do + fill_in "search", with: "rspec" + click_button "Go" + end + step 'I search for "Wiki content"' do fill_in "dashboard_search", with: "content" click_button "Search" @@ -95,7 +100,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps step 'I should see "test_wiki" link in the search results' do page.within('.results') do - find(:css, '.search-results').should have_link 'test_wiki.md' + expect(find(:css, '.search-results')).to have_link 'test_wiki' end end @@ -103,4 +108,8 @@ class Spinach::Features::Search < Spinach::FeatureSteps @wiki = ::ProjectWiki.new(project, current_user) @wiki.create_page("test_wiki", "Some Wiki content", :markdown, "first commit") end + + step 'project "Shop" is public' do + project.update_attributes(visibility_level: Project::PUBLIC) + end end diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb index eb2ccd9d01e..0bee91d758d 100644 --- a/features/steps/shared/active_tab.rb +++ b/features/steps/shared/active_tab.rb @@ -6,7 +6,7 @@ module SharedActiveTab end def ensure_active_sub_tab(content) - expect(find('div.content ul.center-top-menu li.active')).to have_content(content) + expect(find('div.content ul.nav-links li.active')).to have_content(content) end def ensure_active_sub_nav(content) @@ -18,7 +18,7 @@ module SharedActiveTab end step 'no other sub tabs should be active' do - expect(page).to have_selector('div.content ul.center-top-menu li.active', count: 1) + expect(page).to have_selector('div.content ul.nav-links li.active', count: 1) end step 'no other sub navs should be active' do diff --git a/features/steps/shared/builds.rb b/features/steps/shared/builds.rb new file mode 100644 index 00000000000..c4c7672a432 --- /dev/null +++ b/features/steps/shared/builds.rb @@ -0,0 +1,78 @@ +module SharedBuilds + include Spinach::DSL + + step 'project has CI enabled' do + @project.enable_ci + end + + step 'project has coverage enabled' do + @project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/) + end + + step 'project has a recent build' do + @ci_commit = create(:ci_commit, project: @project, sha: @project.commit.sha) + @build = create(:ci_build_with_coverage, commit: @ci_commit) + end + + step 'recent build is successful' do + @build.update_column(:status, 'success') + end + + step 'recent build failed' do + @build.update_column(:status, 'failed') + end + + step 'project has another build that is running' do + create(:ci_build, commit: @ci_commit, name: 'second build', status: 'running') + end + + step 'I visit recent build details page' do + visit namespace_project_build_path(@project.namespace, @project, @build) + end + + step 'I visit project builds page' do + visit namespace_project_builds_path(@project.namespace, @project) + end + + step 'recent build has artifacts available' do + artifacts = Rails.root + 'spec/fixtures/ci_build_artifacts.zip' + archive = fixture_file_upload(artifacts, 'application/zip') + @build.update_attributes(artifacts_file: archive) + end + + step 'recent build has artifacts metadata available' do + metadata = Rails.root + 'spec/fixtures/ci_build_artifacts_metadata.gz' + gzip = fixture_file_upload(metadata, 'application/x-gzip') + @build.update_attributes(artifacts_metadata: gzip) + end + + step 'recent build has a build trace' do + @build.trace = 'build trace' + end + + step 'download of build artifacts archive starts' do + expect(page.response_headers['Content-Type']).to eq 'application/zip' + expect(page.response_headers['Content-Transfer-Encoding']).to eq 'binary' + end + + step 'I access artifacts download page' do + visit download_namespace_project_build_artifacts_path(@project.namespace, @project, @build) + end + + step 'I see details of a build' do + expect(page).to have_content "Build ##{@build.id}" + end + + step 'I see build trace' do + expect(page).to have_css '#build-trace' + end + + step 'I see the build' do + page.within('.build') do + expect(page).to have_content "##{@build.id}" + expect(page).to have_content @build.sha[0..7] + expect(page).to have_content @build.ref + expect(page).to have_content @build.name + end + end +end diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index c6a0ae2ba38..906b66a4a63 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -23,7 +23,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[rel$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "Typo, please fix" find(".js-comment-button").trigger("click") sleep 0.05 @@ -33,7 +33,7 @@ module SharedDiffNote step 'I leave a diff comment in a parallel view on the left side like "Old comment"' do click_parallel_diff_line(sample_commit.line_code, 'old') - page.within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "Old comment" find(".js-comment-button").trigger("click") end @@ -41,7 +41,7 @@ module SharedDiffNote step 'I leave a diff comment in a parallel view on the right side like "New comment"' do click_parallel_diff_line(sample_commit.line_code, 'new') - page.within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "New comment" find(".js-comment-button").trigger("click") end @@ -51,7 +51,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[rel$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "Should fix it :smile:" find('.js-md-preview-button').click end @@ -62,7 +62,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.del_line_code) - page.within("form[rel$='#{sample_commit.del_line_code}']") do + page.within("form[id$='#{sample_commit.del_line_code}']") do fill_in "note[note]", with: "DRY this up" find('.js-md-preview-button').click end @@ -91,16 +91,16 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[rel$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}']") do fill_in 'note[note]', with: ':smile:' - click_button('Add Comment') + click_button('Comment') end end end step 'I submit the diff comment' do page.within(diff_file_selector) do - click_button("Add Comment") + click_button("Comment") end end diff --git a/features/steps/shared/issuable.rb b/features/steps/shared/issuable.rb index e6d1b8b8efc..b6d70a26c21 100644 --- a/features/steps/shared/issuable.rb +++ b/features/steps/shared/issuable.rb @@ -5,6 +5,99 @@ module SharedIssuable find(:css, '.issuable-edit').click end + step 'project "Community" has "Community issue" open issue' do + create_issuable_for_project( + project_name: 'Community', + title: 'Community issue' + ) + end + + step 'project "Community" has "Community fix" open merge request' do + create_issuable_for_project( + project_name: 'Community', + type: :merge_request, + title: 'Community fix' + ) + end + + step 'project "Enterprise" has "Enterprise issue" open issue' do + create_issuable_for_project( + project_name: 'Enterprise', + title: 'Enterprise issue' + ) + end + + step 'project "Enterprise" has "Enterprise fix" open merge request' do + create_issuable_for_project( + project_name: 'Enterprise', + type: :merge_request, + title: 'Enterprise fix' + ) + end + + step 'I leave a comment referencing issue "Community issue"' do + leave_reference_comment( + issuable: Issue.find_by(title: 'Community issue'), + from_project_name: 'Enterprise' + ) + end + + step 'I leave a comment referencing issue "Community fix"' do + leave_reference_comment( + issuable: MergeRequest.find_by(title: 'Community fix'), + from_project_name: 'Enterprise' + ) + end + + step 'I visit issue page "Enterprise issue"' do + issue = Issue.find_by(title: 'Enterprise issue') + visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) + end + + step 'I visit merge request page "Enterprise fix"' do + mr = MergeRequest.find_by(title: 'Enterprise fix') + visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + end + + step 'I visit issue page "Community issue"' do + issue = Issue.find_by(title: 'Community issue') + visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) + end + + step 'I visit issue page "Community fix"' do + mr = MergeRequest.find_by(title: 'Community fix') + visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + end + + step 'I should not see any related merge requests' do + page.within '.issue-details' do + expect(page).not_to have_content('.merge-requests') + end + end + + step 'I should see the "Enterprise fix" related merge request' do + page.within '.merge-requests' do + expect(page).to have_content('1 Related Merge Request') + expect(page).to have_content('Enterprise fix') + end + end + + step 'I should see a note linking to "Enterprise fix" merge request' do + visible_note( + issuable: MergeRequest.find_by(title: 'Enterprise fix'), + from_project_name: 'Community', + user_name: 'Mary Jane' + ) + end + + step 'I should see a note linking to "Enterprise issue" issue' do + visible_note( + issuable: Issue.find_by(title: 'Enterprise issue'), + from_project_name: 'Community', + user_name: 'Mary Jane' + ) + end + step 'I click link "Edit" for the merge request' do edit_issuable end @@ -12,4 +105,102 @@ module SharedIssuable step 'I click link "Edit" for the issue' do edit_issuable end + + step 'I sort the list by "Oldest updated"' do + find('button.dropdown-toggle.btn').click + page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + click_link "Oldest updated" + end + end + + step 'I sort the list by "Least popular"' do + find('button.dropdown-toggle.btn').click + + page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + click_link 'Least popular' + end + end + + step 'I sort the list by "Most popular"' do + find('button.dropdown-toggle.btn').click + + page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + click_link 'Most popular' + end + end + + step 'The list should be sorted by "Oldest updated"' do + page.within('div.dropdown.inline.prepend-left-10') do + expect(page.find('button.dropdown-toggle.btn')).to have_content('Oldest updated') + end + end + + step 'I should see "1 of 1" in the sidebar' do + expect_sidebar_content('1 of 1') + end + + step 'I should see "1 of 2" in the sidebar' do + expect_sidebar_content('1 of 2') + end + + step 'I should see "2 of 2" in the sidebar' do + expect_sidebar_content('2 of 2') + end + + step 'I should see "3 of 3" in the sidebar' do + expect_sidebar_content('3 of 3') + end + + step 'I click link "Next" in the sidebar' do + page.within '.issuable-sidebar' do + click_link 'Next' + end + end + + def create_issuable_for_project(project_name:, title:, type: :issue) + project = Project.find_by(name: project_name) + + attrs = { + title: title, + author: project.users.first, + description: '# Description header' + } + + case type + when :issue + attrs.merge!(project: project) + when :merge_request + attrs.merge!( + source_project: project, + target_project: project, + source_branch: 'fix', + target_branch: 'master' + ) + end + + create(type, attrs) + end + + def leave_reference_comment(issuable:, from_project_name:) + project = Project.find_by(name: from_project_name) + + page.within('.js-main-target-form') do + fill_in 'note[note]', with: "##{issuable.to_reference(project)}" + click_button 'Comment' + end + end + + def visible_note(issuable:, from_project_name:, user_name:) + project = Project.find_by(name: from_project_name) + + expect(page).to have_content(user_name) + expect(page).to have_content("mentioned in #{issuable.class.to_s.titleize.downcase} #{issuable.to_reference(project)}") + end + + def expect_sidebar_content(content) + page.within '.issuable-sidebar' do + expect(page).to have_content content + end + end + end diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index f6aabfefeff..fb0462d6e04 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -17,7 +17,7 @@ module SharedNote step 'I leave a comment like "XML attached"' do page.within(".js-main-target-form") do fill_in "note[note]", with: "XML attached" - click_button "Add Comment" + click_button "Comment" end end @@ -30,7 +30,7 @@ module SharedNote step 'I submit the comment' do page.within(".js-main-target-form") do - click_button "Add Comment" + click_button "Comment" end end @@ -106,12 +106,16 @@ module SharedNote end end + step 'I should see no notes at all' do + expect(page).to_not 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 "Add Comment" + click_button "Comment" sleep 0.05 end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index b33bd332655..2bd8ea745e4 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -7,6 +7,10 @@ module SharedPaths visit new_project_path end + step 'I visit login page' do + visit new_user_session_path + end + # ---------------------------------------- # User # ---------------------------------------- @@ -23,6 +27,10 @@ module SharedPaths visit group_path(Group.find_by(name: "Owned")) end + step 'I visit group "Owned" activity page' do + visit activity_group_path(Group.find_by(name: "Owned")) + end + step 'I visit group "Owned" issues page' do visit issues_group_path(Group.find_by(name: "Owned")) end @@ -103,6 +111,10 @@ module SharedPaths visit dashboard_groups_path end + step 'I visit dashboard todos page' do + visit dashboard_todos_path + end + step 'I should be redirected to the dashboard groups page' do expect(current_path).to eq dashboard_groups_path end @@ -183,6 +195,10 @@ module SharedPaths visit admin_groups_path end + step 'I visit admin appearance page' do + visit admin_appearances_path + end + step 'I visit admin teams page' do visit admin_teams_path end @@ -191,6 +207,10 @@ module SharedPaths visit admin_application_settings_path end + step 'I visit spam logs page' do + visit admin_spam_logs_path + end + step 'I visit applications page' do visit admin_applications_path end @@ -259,6 +279,10 @@ module SharedPaths visit namespace_project_deploy_keys_path(@project.namespace, @project) end + step 'I visit project find file page' do + visit namespace_project_find_file_path(@project.namespace, @project, root_ref) + end + # ---------------------------------------- # "Shop" Project # ---------------------------------------- @@ -368,13 +392,19 @@ module SharedPaths end step 'I visit merge request page "Bug NS-04"' do - mr = MergeRequest.find_by(title: "Bug NS-04") - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + visit merge_request_path("Bug NS-04") end step 'I visit merge request page "Bug NS-05"' do - mr = MergeRequest.find_by(title: "Bug NS-05") - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + visit merge_request_path("Bug NS-05") + end + + step 'I visit merge request page "Bug NS-07"' do + visit merge_request_path("Bug NS-07") + end + + step 'I visit merge request page "Bug NS-08"' do + visit merge_request_path("Bug NS-08") end step 'I visit merge request page "Bug CO-01"' do @@ -435,6 +465,10 @@ module SharedPaths visit namespace_project_path(project.namespace, project) end + step "I should not see command line instructions" do + expect(page).not_to have_css('.empty_wrapper') + end + # ---------------------------------------- # Public Projects # ---------------------------------------- @@ -479,6 +513,11 @@ module SharedPaths Project.find_by!(name: 'Shop') end + def merge_request_path(title) + mr = MergeRequest.find_by(title: title) + namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + end + # ---------------------------------------- # Errors # ---------------------------------------- diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index da643bf3ba9..b13e82f276b 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -7,6 +7,11 @@ module SharedProject @project.team << [@user, :master] end + step "project exists in some group namespace" do + @group = create(:group, name: 'some group') + @project = create(:project, namespace: @group) + end + # Create a specific project called "Shop" step 'I own project "Shop"' do @project = Project.find_by(name: "Shop") @@ -98,6 +103,18 @@ module SharedProject end # ---------------------------------------- + # Project permissions + # ---------------------------------------- + + step 'I am member of a project with a guest role' do + @project.team << [@user, Gitlab::Access::GUEST] + end + + step 'I am member of a project with a reporter role' do + @project.team << [@user, Gitlab::Access::REPORTER] + end + + # ---------------------------------------- # Visibility of archived project # ---------------------------------------- @@ -161,24 +178,33 @@ module SharedProject end step '"John Doe" owns private project "Enterprise"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Enterprise") - project ||= create(:empty_project, name: "Enterprise", namespace: user.namespace) - project.team << [user, :master] + user_owns_project( + user_name: 'John Doe', + project_name: 'Enterprise' + ) + end + + step '"Mary Jane" owns private project "Enterprise"' do + user_owns_project( + user_name: 'Mary Jane', + project_name: 'Enterprise' + ) end step '"John Doe" owns internal project "Internal"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Internal") - project ||= create :empty_project, :internal, name: 'Internal', namespace: user.namespace - project.team << [user, :master] + user_owns_project( + user_name: 'John Doe', + project_name: 'Internal', + visibility: :internal + ) end step '"John Doe" owns public project "Community"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Community") - project ||= create :empty_project, :public, name: 'Community', namespace: user.namespace - project.team << [user, :master] + user_owns_project( + user_name: 'John Doe', + project_name: 'Community', + visibility: :public + ) end step 'public empty project "Empty Public Project"' do @@ -213,4 +239,23 @@ module SharedProject expect(page).to have_content("skipped") end end + + step 'The project is internal' do + @project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + end + + step 'public access for builds is enabled' do + @project.update(public_builds: true) + end + + step 'public access for builds is disabled' do + @project.update(public_builds: false) + 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) + project ||= create(:empty_project, visibility, name: project_name, namespace: user.namespace) + project.team << [user, :master] + end end diff --git a/features/steps/shared/user.rb b/features/steps/shared/user.rb index f0721094ee3..9856c510aa0 100644 --- a/features/steps/shared/user.rb +++ b/features/steps/shared/user.rb @@ -26,4 +26,20 @@ module SharedUser step 'I have no ssh keys' do @user.keys.delete_all end + + step 'I click on "Personal projects" tab' do + page.within '.nav-links' do + click_link 'Personal projects' + end + + expect(page).to have_css('.tab-content #projects.active') + end + + step 'I click on "Contributed projects" tab' do + page.within '.nav-links' do + click_link 'Contributed projects' + end + + expect(page).to have_css('.tab-content #contributed.active') + end end diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 4156c7ec484..fe9e39cf509 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -6,14 +6,10 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 90 : 15 Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout) + Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout, window_size: [1366, 768]) end -Spinach.hooks.on_tag("javascript") do - Capybara.current_driver = Capybara.javascript_driver -end - -Capybara.default_wait_time = timeout +Capybara.default_max_wait_time = timeout Capybara.ignore_hidden_elements = false unless ENV['CI'] || ENV['CI_SERVER'] @@ -22,3 +18,7 @@ unless ENV['CI'] || ENV['CI_SERVER'] # Keep only the screenshots generated from the last failing test suite Capybara::Screenshot.prune_strategy = :keep_last_run end + +Spinach.hooks.before_run do + TestEnv.warm_asset_cache +end diff --git a/features/support/env.rb b/features/support/env.rb index 62c80b9c948..357d164d87f 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -14,6 +14,7 @@ require 'sidekiq/testing/inline' require_relative 'capybara' require_relative 'db_cleaner' +require_relative 'rerun' %w(select2_helper test_env repo_helpers).each do |f| require Rails.root.join('spec', 'support', f) diff --git a/features/support/rerun.rb b/features/support/rerun.rb new file mode 100644 index 00000000000..8b176c5be89 --- /dev/null +++ b/features/support/rerun.rb @@ -0,0 +1,14 @@ +# The spinach-rerun-reporter doesn't define the on_undefined_step +# See it here: https://github.com/javierav/spinach-rerun-reporter/blob/master/lib/spinach/reporter/rerun.rb +module Spinach + class Reporter + class Rerun + def on_undefined_step(step_data, failure, step_definitions = nil) + super step_data, failure, step_definitions + + # save feature file and scenario line + @rerun << "#{current_feature.filename}:#{current_scenario.line}" + end + end + end +end diff --git a/features/user.feature b/features/user.feature index 35eae842e77..e0cadba30a1 100644 --- a/features/user.feature +++ b/features/user.feature @@ -5,10 +5,12 @@ Feature: User # Signed out + @javascript Scenario: I visit user "John Doe" page while not signed in when he owns a public project Given "John Doe" owns internal project "Internal" And "John Doe" owns public project "Community" When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should not see project "Enterprise" And I should not see project "Internal" @@ -16,28 +18,34 @@ Feature: User # Signed in as someone else + @javascript Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project Given "John Doe" owns public project "Community" And "John Doe" owns internal project "Internal" And I sign in as a user When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should not see project "Enterprise" And I should see project "Internal" And I should see project "Community" + @javascript Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a public project Given "John Doe" owns internal project "Internal" And I sign in as a user When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should not see project "Enterprise" And I should see project "Internal" And I should not see project "Community" + @javascript Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a project I can see Given I sign in as a user When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should not see project "Enterprise" And I should not see project "Internal" @@ -45,19 +53,23 @@ Feature: User # Signed in as the user himself + @javascript Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has a public project Given "John Doe" owns internal project "Internal" And "John Doe" owns public project "Community" And I sign in as "John Doe" When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should see project "Enterprise" And I should see project "Internal" And I should see project "Community" + @javascript Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has no public project Given I sign in as "John Doe" When I visit user "John Doe" page + And I click on "Personal projects" tab Then I should see user "John Doe" page And I should see project "Enterprise" And I should not see project "Internal" @@ -68,6 +80,7 @@ Feature: User Given I sign in as a user And "John Doe" has contributions When I visit user "John Doe" page + And I click on "Contributed projects" tab Then I should see user "John Doe" page And I should see contributed projects And I should see contributions calendar |