summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Flow/tests/browser/features')
-rw-r--r--Flow/tests/browser/features/action_menu_permalink.feature31
-rw-r--r--Flow/tests/browser/features/anon_interface.feature9
-rw-r--r--Flow/tests/browser/features/edit_existing.feature22
-rw-r--r--Flow/tests/browser/features/flow_in_recent_changes.feature18
-rw-r--r--Flow/tests/browser/features/flow_logged_in.feature33
-rw-r--r--Flow/tests/browser/features/flow_no_javascript.feature21
-rw-r--r--Flow/tests/browser/features/lock_unlock_topics.feature48
-rw-r--r--Flow/tests/browser/features/moderation.feature44
-rw-r--r--Flow/tests/browser/features/new_topic.feature15
-rw-r--r--Flow/tests/browser/features/post_links.feature12
-rw-r--r--Flow/tests/browser/features/reply.feature30
-rw-r--r--Flow/tests/browser/features/reply_moderation.feature17
-rw-r--r--Flow/tests/browser/features/sorting_topics.feature19
-rw-r--r--Flow/tests/browser/features/step_definitions/action_menu_permalink_steps.rb41
-rw-r--r--Flow/tests/browser/features/step_definitions/edit_existing_steps.rb47
-rw-r--r--Flow/tests/browser/features/step_definitions/flow_in_recent_changes_steps.rb11
-rw-r--r--Flow/tests/browser/features/step_definitions/flow_no_javascript_steps.rb65
-rw-r--r--Flow/tests/browser/features/step_definitions/flow_steps.rb167
-rw-r--r--Flow/tests/browser/features/step_definitions/lock_unlock_topics_steps.rb75
-rw-r--r--Flow/tests/browser/features/step_definitions/moderation_steps.rb47
-rw-r--r--Flow/tests/browser/features/step_definitions/reply_moderation_steps.rb24
-rw-r--r--Flow/tests/browser/features/step_definitions/reply_steps.rb65
-rw-r--r--Flow/tests/browser/features/step_definitions/sorting_topics_steps.rb34
-rw-r--r--Flow/tests/browser/features/step_definitions/thank_steps.rb37
-rw-r--r--Flow/tests/browser/features/step_definitions/watch_steps.rb64
-rw-r--r--Flow/tests/browser/features/support/env.rb10
-rw-r--r--Flow/tests/browser/features/support/hooks.rb3
-rw-r--r--Flow/tests/browser/features/support/pages/flow_old_permalink_page.rb7
-rw-r--r--Flow/tests/browser/features/support/pages/flow_page.rb239
-rw-r--r--Flow/tests/browser/features/support/pages/new_flow_page.rb7
-rw-r--r--Flow/tests/browser/features/support/pages/recent_changes_page.rb8
-rw-r--r--Flow/tests/browser/features/support/pages/user_page.rb9
-rw-r--r--Flow/tests/browser/features/thank.feature23
-rw-r--r--Flow/tests/browser/features/watch.feature36
34 files changed, 1338 insertions, 0 deletions
diff --git a/Flow/tests/browser/features/action_menu_permalink.feature b/Flow/tests/browser/features/action_menu_permalink.feature
new file mode 100644
index 00000000..d6197117
--- /dev/null
+++ b/Flow/tests/browser/features/action_menu_permalink.feature
@@ -0,0 +1,31 @@
+@chrome @clean @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Actions menu Permalink
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+
+ Scenario: Topic Actions menu Permalink
+ Given I have created a Flow topic with title "Permalinktest"
+ When I click the Topic Actions link
+ And I click Permalink from the Actions menu
+ And I am viewing Topic page
+ Then I see only one topic on the page
+ And the top post should have a heading which contains "Permalinktest"
+
+ Scenario: Actions menu Permalink
+ Given I have created a Flow topic with title "PermalinkReplyTest"
+ And I add 3 comments to the Topic
+ When I click the Post Actions link on the 3rd comment on the topic
+ And I click the Post Actions link on the 3rd comment on the topic
+ And I click Permalink from the 3rd comment Post Actions menu
+ And I am viewing Topic page
+ Then I see only one topic on the page
+ And the highlighted comment should contain the text for the 3rd comment
+
+ Scenario: Old style topic permalink
+ Given I have created a Flow topic with title "Permalinktest"
+ When I go to an old style permalink to my topic
+ And I am viewing Topic page
+ Then I see only one topic on the page
+ And the top post should have a heading which contains "Permalinktest"
diff --git a/Flow/tests/browser/features/anon_interface.feature b/Flow/tests/browser/features/anon_interface.feature
new file mode 100644
index 00000000..37eb3647
--- /dev/null
+++ b/Flow/tests/browser/features/anon_interface.feature
@@ -0,0 +1,9 @@
+@chrome @clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @phantomjs @test2.wikipedia.org
+Feature: Check the interface for anonymous users
+
+ Scenario: Anon does not see block or actions
+ Given I am on Flow page
+ And I have created a Flow topic
+ # which is not hidden (this is implicit from the above step)
+ When I see a flow creator element
+ Then the block author link should not be visible
diff --git a/Flow/tests/browser/features/edit_existing.feature b/Flow/tests/browser/features/edit_existing.feature
new file mode 100644
index 00000000..bbbb24c8
--- /dev/null
+++ b/Flow/tests/browser/features/edit_existing.feature
@@ -0,0 +1,22 @@
+@clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Edit existing title
+
+ Assumes that the test Flow page has at least two topics (with posts).
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+ And I have created a Flow topic
+
+ Scenario: Edit an existing title
+ When I click the Edit title action
+ And I edit the title field with Title edited
+ And I save the new title
+ Then the top post should have a heading which contains "Title edited"
+
+ @phantomjs
+ Scenario: Edit existing post
+ When I click Edit post
+ And I edit the post field with Post edited
+ And I save the new post
+ Then the saved post should contain Post edited
diff --git a/Flow/tests/browser/features/flow_in_recent_changes.feature b/Flow/tests/browser/features/flow_in_recent_changes.feature
new file mode 100644
index 00000000..d8ba83ff
--- /dev/null
+++ b/Flow/tests/browser/features/flow_in_recent_changes.feature
@@ -0,0 +1,18 @@
+@clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Flow updates are in Recent Changes
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+ And I have created a Flow topic with title "New topic should be in Recent Changes"
+
+ Scenario: New topic is in Recent Changes
+ When I navigate to the Recent Changes page
+ Then the new topic should be in the Recent Changes page
+
+ Scenario: Edited topic is in Recent Changes
+ When I click the Edit title action
+ And I edit the title field with Title should be in Recent Changes
+ And I save the new title
+ And I navigate to the Recent Changes page
+ Then the new title should be in the Recent Changes page
diff --git a/Flow/tests/browser/features/flow_logged_in.feature b/Flow/tests/browser/features/flow_logged_in.feature
new file mode 100644
index 00000000..596db0aa
--- /dev/null
+++ b/Flow/tests/browser/features/flow_logged_in.feature
@@ -0,0 +1,33 @@
+@chrome @clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @login @test2.wikipedia.org
+Feature: Create new topic logged in
+
+ It requires the cldr extension, a "Flow QA" page, and a "Selenium user" who has
+ permission to flow-delete (usually 'sysop'/administrator user right), to
+ flow-suppress (usually the 'oversight' user right), and to block (usually 'sysop').
+ If the Selenium_user's Flow editor is VisualEditor, then the flow_page
+ definitions have to change.
+
+ Background:
+ Given I am logged in
+ And I have created a Flow topic
+
+ Scenario: Add new Flow topic and show author and block links
+ Given the author link is visible
+ And the talk to author link is not visible
+ And the block author link is not visible
+ # hover doesn't work in IE, bug 67723
+ When I hover over the author link
+ Then the talk to author link should be visible
+ And the block author link should be visible
+
+ Scenario: Post Actions
+ When I click the Post Actions link
+ Then I should see a Hide button
+ And I should see a Delete button
+ And I should see a Suppress button
+
+ Scenario: Topic Actions
+ When I click the Topic Actions link
+ Then I should see a Hide topic button
+ And I should see a Delete topic button
+ And I should see a Suppress topic button
diff --git a/Flow/tests/browser/features/flow_no_javascript.feature b/Flow/tests/browser/features/flow_no_javascript.feature
new file mode 100644
index 00000000..439bbd6c
--- /dev/null
+++ b/Flow/tests/browser/features/flow_no_javascript.feature
@@ -0,0 +1,21 @@
+@custom-browser @en.wikipedia.beta.wmflabs.org @firefox @login @test2.m.wikipedia.org
+Feature: Basic site for legacy devices
+
+ Background:
+ Given I am using user agent "Mozilla/4.0 (compatible; MSIE 5.5b1; Mac_PowerPC)"
+ And I am on a Flow page without JavaScript
+
+ Scenario: I post a new topic without JavaScript
+ When I see the form to post a new topic
+ And I click Add topic no javascript
+ And I enter a no javascript topic title of "Selenium no javascript title"
+ And I enter a no javascript topic body of "Selenium no javascript body"
+ And I save a no javascript new topic
+ Then the page contains my no javascript topic
+ And the page contains my no javascript body
+
+ Scenario: I reply to a topic without JavaScript
+ When I see the form to reply to a topic
+ And I enter a no javascript reply of "Selenium no javascript reply"
+ And I save a no javascript reply
+ Then the page contains my no javascript reply
diff --git a/Flow/tests/browser/features/lock_unlock_topics.feature b/Flow/tests/browser/features/lock_unlock_topics.feature
new file mode 100644
index 00000000..062c3049
--- /dev/null
+++ b/Flow/tests/browser/features/lock_unlock_topics.feature
@@ -0,0 +1,48 @@
+@chrome @clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @login @test2.wikipedia.org
+Feature: Lock and unlock topics
+
+ Background:
+ Given I am logged in
+
+ @wip
+ Scenario: Locked topics have no reply links
+ Given I am on Flow page
+ And I have created a Flow topic
+ And the top post has been locked
+ When I expand the top post
+ Then the original message for the top post should have no reply link
+ And the original message for the top post should have no edit link
+
+ @internet_explorer_10
+ Scenario: Locking a topic and then changing your mind
+ Given I am on Flow page
+ And I have created a Flow topic
+ When I click the Topic Actions link
+ And I click the Lock topic button
+ And I cancel the lock/unlock topic form
+ Then the top post should be an open discussion
+ And I should not see the lock/unlock form
+
+ @internet_explorer_10
+ Scenario: Locking a topic
+ Given I am on Flow page
+ And I have created a Flow topic
+ When I click the Topic Actions link
+ And I click the Lock topic button
+ And I type "This is a bikeshed" as the reason
+ And I submit the lock/unlock topic form
+ Then the top post should be a locked discussion
+ And the reason of the first topic should be "This is a bikeshed"
+ And the content of the top post should be visible
+
+ # Close-then-unlock doesn't work in IE, it caches the API response (bug 69160).
+ Scenario: Opening a topic
+ Given I am on Flow page
+ And I have created a Flow topic
+ And the top post has been locked
+ And I click the Topic Actions link
+ And I click the Unlock topic button
+ When I type "Fun discussion" as the reason
+ And I submit the lock/unlock topic form
+ Then the top post should be an open discussion
+ And the content of the top post should be visible
diff --git a/Flow/tests/browser/features/moderation.feature b/Flow/tests/browser/features/moderation.feature
new file mode 100644
index 00000000..3fa14415
--- /dev/null
+++ b/Flow/tests/browser/features/moderation.feature
@@ -0,0 +1,44 @@
+@chrome @clean @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Moderation
+
+ Assumes Flow is enabled for the User_talk namespace.
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+
+ Scenario: Deleting a topic
+ Given I have created a Flow topic with title "Deletemeifyoudare"
+ When I click the Topic Actions link
+ And I click the Delete topic button
+ And I see a dialog box
+ And I give reason for deletion as being "He's a naughty boy"
+ And I click Delete topic
+ Then the top post should be marked as deleted
+
+ Scenario: Suppressing a topic
+ Given I have created a Flow topic with title "Suppressmeifyoudare"
+ When I click the Topic Actions link
+ And I click the Suppress topic button
+ And I see a dialog box
+ And I give reason for suppression as being "Quelling the peasants"
+ And I click Suppress topic
+ Then the top post should be marked as suppressed
+
+ Scenario: Cancelling a dialog without text
+ Given I have created a Flow topic with title "Testing cancel deletion of topic"
+ When I click the Topic Actions link
+ And I click the Delete topic button
+ And I see a dialog box
+ And I cancel the dialog
+ Then I do not see the dialog box
+
+ Scenario: Cancelling a dialog with text
+ Given I have created a Flow topic with title "Testing cancel deletion of topic"
+ When I click the Topic Actions link
+ And I click the Delete topic button
+ And I see a dialog box
+ And I give reason for suppression as being "About to change my mind"
+ And I cancel the dialog
+ And I confirm
+ Then I do not see the dialog box
diff --git a/Flow/tests/browser/features/new_topic.feature b/Flow/tests/browser/features/new_topic.feature
new file mode 100644
index 00000000..78494bbd
--- /dev/null
+++ b/Flow/tests/browser/features/new_topic.feature
@@ -0,0 +1,15 @@
+@chrome @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @phantomjs @test2.wikipedia.org
+Feature: Creating a new topic
+
+ Background:
+ Given I am on Flow page
+
+ Scenario: Cannot create a new topic without content
+ When I type "Anonymous user topic creation test" into the new topic title field
+ Then the Save New Topic button should be disabled
+
+ Scenario: Add new Flow topic as anonymous user
+ When I have created a Flow topic with title "Anonymous user topic creation"
+ # TODO the terminology below is terrible, posts don't have headings. It's the top topic's title and first post.
+ Then the top post should have a heading which contains "Anonymous user topic creation"
+ And the top post should have content which contains "Anonymous user topic creation"
diff --git a/Flow/tests/browser/features/post_links.feature b/Flow/tests/browser/features/post_links.feature
new file mode 100644
index 00000000..1ad2dfcd
--- /dev/null
+++ b/Flow/tests/browser/features/post_links.feature
@@ -0,0 +1,12 @@
+@chrome @clean @ee-prototype.wmflabs.org @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Follow user links
+
+ Scenario: User links takes me to the user page
+ Given I am logged in
+ And I am on Flow page
+ And I have created a Flow topic
+ And I see a flow creator element
+ When I click the flow creator element
+ Then I am on my user page
+
+
diff --git a/Flow/tests/browser/features/reply.feature b/Flow/tests/browser/features/reply.feature
new file mode 100644
index 00000000..a9bc50ea
--- /dev/null
+++ b/Flow/tests/browser/features/reply.feature
@@ -0,0 +1,30 @@
+@chrome @clean @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Replying
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+
+ @phantomjs
+ Scenario: I can reply
+ Given I have created a Flow topic with title "Reply test"
+ When I reply with comment "Boom boom shake shake the room"
+ Then the top post's first reply should contain the text "Boom boom shake shake the room"
+
+ @phantomjs
+ Scenario: Replying updates watched state
+ Given I have created a Flow topic with title "Reply watch test"
+ And I am not watching my new Flow topic
+ When I reply with comment "I want to watch this title"
+ Then I should see an unwatch link on the topic
+
+# TODO maybe should test simple Cancelling reply as well.
+
+ Scenario: Previewing reply, continue editing, then cancel leaves usable form
+ Given I have created a Flow topic with title "Reply preview test"
+ When I start a reply with comment "my form lies over the ocean"
+ And I click the Preview button
+ And I click the Keep editing button
+ And I click the Cancel button and confirm the dialog
+ And I start a reply with comment "bring back my form to me"
+ Then I should see the topic reply form
diff --git a/Flow/tests/browser/features/reply_moderation.feature b/Flow/tests/browser/features/reply_moderation.feature
new file mode 100644
index 00000000..c52a5954
--- /dev/null
+++ b/Flow/tests/browser/features/reply_moderation.feature
@@ -0,0 +1,17 @@
+@chrome @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Reply moderation
+
+ Background:
+ Given I am logged in
+ And I am on Flow page
+
+ Scenario: Hiding a comment
+ Given I have created a Flow topic with title "Hide comment test"
+ And I add 3 comments to the Topic
+ When I click the Post Actions link on the 3rd comment on the topic
+ And I click Hide comment button
+ And I see a dialog box
+ And I give reason for hiding as being "Shhhh!"
+ And I click the Hide button in the dialog
+ Then the 3rd comment should be marked as hidden
+ And the content of the 3rd comment should not be visible
diff --git a/Flow/tests/browser/features/sorting_topics.feature b/Flow/tests/browser/features/sorting_topics.feature
new file mode 100644
index 00000000..a1bcc8ea
--- /dev/null
+++ b/Flow/tests/browser/features/sorting_topics.feature
@@ -0,0 +1,19 @@
+@chrome @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @phantomjs @test2.wikipedia.org
+Feature: Sorting topics
+
+ Background:
+ Given I am on Flow page
+
+ Scenario: Switch topic sorting to Recently Active Topics
+ When I click Newest topics link
+ And I click Recently active topics choice
+ Then the Flow page should show Recently active topics link
+ And the Flow page should not show Newest topics link
+
+ Scenario: Switch topic sorting to Recently Active Topics and then back to Newest topics
+ When I click Newest topics link
+ And I click Recently active topics choice
+ And I click Recently active topics link
+ And I click Newest topics choice
+ Then the Flow page should show Newest topics link
+ And the Flow page should not show Recently active topics link
diff --git a/Flow/tests/browser/features/step_definitions/action_menu_permalink_steps.rb b/Flow/tests/browser/features/step_definitions/action_menu_permalink_steps.rb
new file mode 100644
index 00000000..614e47db
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/action_menu_permalink_steps.rb
@@ -0,0 +1,41 @@
+When(/^I add (\d+) comments to the Topic$/) do |number|
+ number.to_i.times do
+ @saved_random = Random.new.rand.to_s
+ step 'I reply with comment "' + 'Selenium comment ' + @saved_random + '"'
+ end
+end
+
+When(/^I click Permalink from the Actions menu$/) do
+ on(FlowPage).permalink_button_element.when_present.click
+end
+
+When(/^I click Permalink from the 3rd comment Post Actions menu$/) do
+ on(FlowPage).actions_link_permalink_3rd_comment_element.when_present.click
+end
+
+When(/^I click the Post Actions link on the 3rd comment on the topic$/) do
+ on(FlowPage) do |page|
+ page.third_post_actions_link_element.when_present.focus
+ page.third_post_actions_link_element.click
+ end
+end
+
+When(/^I go to an old style permalink to my topic$/) do
+ on(FlowPage) do |curPage|
+ work_flow_id = curPage.flow_first_topic_element.attribute('data-flow-id')
+ visit(FlowOldPermalinkPage, using_params: { workflow_id: work_flow_id })
+ end
+end
+
+Then(/^I see only one topic on the page$/) do
+ on(FlowPage) do |page|
+ # We should have the a post with a heading
+ expect(page.flow_first_topic_heading_element.when_present).to be_visible
+ # but this should match nothing - there is only one topic.
+ expect(page.flow_second_topic_heading_element).not_to be_visible
+ end
+end
+
+Then(/^the highlighted comment should contain the text for the 3rd comment$/) do
+ expect(on(FlowPage).highlighted_post).to match @saved_random
+end
diff --git a/Flow/tests/browser/features/step_definitions/edit_existing_steps.rb b/Flow/tests/browser/features/step_definitions/edit_existing_steps.rb
new file mode 100644
index 00000000..e743ea96
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/edit_existing_steps.rb
@@ -0,0 +1,47 @@
+When(/^I click Edit post$/) do
+ on(FlowPage) do |page|
+ page.edit_post_element.when_present.click
+ end
+end
+
+When(/^I click the Edit title action$/) do
+ on(FlowPage) do |page|
+ page.topic_actions_link_element.when_present.click
+ page.edit_title_button_element.when_present.click
+ end
+end
+
+When(/^I edit the post field with (.+)$/) do |edited_post|
+ on(FlowPage) do |page|
+ # Take focus away from menu
+ page.post_edit_element.when_present.click
+ page.post_edit_element.when_present.send_keys(edited_post + @random_string)
+ end
+end
+
+When(/^I edit the title field with (.+)$/) do |edited_title|
+ on(FlowPage) do |page|
+ @edited_topic_string = edited_title + @random_string
+ # Take focus away from menu
+ page.title_edit_element.when_present.click
+ page.title_edit_element.when_present.send_keys(@edited_topic_string)
+ end
+end
+
+When(/^I save the new post/) do
+ on(FlowPage) do |page|
+ page.change_post_save_element.when_present.click
+ page.change_post_save_element.when_not_present
+ end
+end
+
+When(/^I save the new title$/) do
+ on(FlowPage) do |page|
+ page.change_title_save_element.when_present.click
+ page.flow_first_topic_heading_element.when_present
+ end
+end
+
+Then(/^the saved post should contain (.+)$/) do |edited_post|
+ expect(on(FlowPage).flow_first_topic_body).to match(edited_post + @random_string)
+end
diff --git a/Flow/tests/browser/features/step_definitions/flow_in_recent_changes_steps.rb b/Flow/tests/browser/features/step_definitions/flow_in_recent_changes_steps.rb
new file mode 100644
index 00000000..7828377b
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/flow_in_recent_changes_steps.rb
@@ -0,0 +1,11 @@
+When(/^I navigate to the Recent Changes page$/) do
+ visit(RecentChangesPage)
+end
+
+Then(/^the new topic should be in the Recent Changes page$/) do
+ expect(on(RecentChangesPage).recent_changes_element.when_present.text).to match @topic_string
+end
+
+Then(/^the new title should be in the Recent Changes page$/) do
+ expect(on(RecentChangesPage).recent_changes_element.when_present.text).to match @edited_topic_string
+end
diff --git a/Flow/tests/browser/features/step_definitions/flow_no_javascript_steps.rb b/Flow/tests/browser/features/step_definitions/flow_no_javascript_steps.rb
new file mode 100644
index 00000000..765c4589
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/flow_no_javascript_steps.rb
@@ -0,0 +1,65 @@
+# This test has no javascript
+# Therefore this test has no AJAX
+# Therefore it should run without any "when_present" clauses
+# If you need a "when_present" to make the test run, that is a bug
+
+Given(/^I am on a Flow page without JavaScript$/) do
+ visit(FlowPage)
+end
+
+Given(/^I am using user agent "(.+)"$/) do |user_agent|
+ @user_agent = user_agent
+ @browser = browser(test_name(@scenario), { user_agent: user_agent })
+ $session_id = @browser.driver.instance_variable_get(:@bridge).session_id
+end
+
+When(/^I click Add topic no javascript$/) do
+ on(FlowPage).no_javascript_topic_title_text_element.click
+end
+
+When(/^I enter a no javascript reply of "(.*?)"$/) do |no_javascript_reply|
+ @no_javascript_reply = no_javascript_reply
+ on(FlowPage).no_javascript_reply_form_element.send_keys "#{@no_javascript_reply} #{@random_string}"
+end
+
+When(/^I enter a no javascript topic body of "(.*?)"$/) do |no_javascript_topic_body|
+ @no_javascript_topic_body = no_javascript_topic_body
+ on(FlowPage).no_javascript_topic_body_text_element.send_keys "#{@no_javascript_topic_body} #{@random_string}"
+end
+
+When(/^I enter a no javascript topic title of "(.*?)"$/) do |no_javascript_topic_title|
+ @no_javascript_topic_title = no_javascript_topic_title
+ on(FlowPage).no_javascript_topic_title_text_element.send_keys "#{@no_javascript_topic_title} #{@random_string}"
+end
+
+When(/^I save a no javascript new topic$/) do
+ on(FlowPage).no_javascript_add_topic_element.click
+end
+
+When(/^I save a no javascript reply$/) do
+ on(FlowPage).no_javascript_reply_element.click
+end
+
+When(/^I see the form to post a new topic$/) do
+ on(FlowPage) do |page|
+ page.no_javascript_start_topic_element.click
+ end
+end
+
+When(/^I see the form to reply to a topic$/) do
+ on(FlowPage) do |page|
+ page.no_javascript_start_reply_element.click
+ end
+end
+
+Then(/^the page contains my no javascript body$/) do
+ expect(on(FlowPage).no_javascript_page_content_body).to match "#{@no_javascript_topic_body} #{@random_string}"
+end
+
+Then(/^the page contains my no javascript topic$/) do
+ expect(on(FlowPage).no_javascript_page_content_title).to match "#{@no_javascript_topic_title} #{@random_string}"
+end
+
+Then(/^the page contains my no javascript reply$/) do
+ expect(on(FlowPage).no_javascript_page_flow_topics).to match "#{@no_javascript_reply} #{@random_string}"
+end
diff --git a/Flow/tests/browser/features/step_definitions/flow_steps.rb b/Flow/tests/browser/features/step_definitions/flow_steps.rb
new file mode 100644
index 00000000..55509d2e
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/flow_steps.rb
@@ -0,0 +1,167 @@
+Given(/^I am on a new board$/) do
+ visit NewFlowPage
+end
+
+Given(/^I am on Flow page$/) do
+ visit FlowPage
+ step "The Flow page is fully loaded"
+ step "page has no ResourceLoader errors"
+end
+
+# @todo: Rewrite to use more generic step below
+Given(/^I have created a Flow topic$/) do
+ step "I have created a Flow topic with title \"Title of Flow topic\""
+end
+
+Given(/^I have created a Flow topic with title "(.+)"$/) do |title|
+ step "I am on Flow page"
+ step "I type \"" + title + "\" into the new topic title field"
+ step "I type \"" + title + "\" into the new topic content field"
+ step "I click New topic save"
+end
+
+Given(/^the author link is visible$/) do
+ on(FlowPage).author_link_element.when_present.when_present
+end
+
+Given(/^the block author link is not visible$/) do
+ on(FlowPage).usertools_block_user_link_element.when_not_visible
+end
+
+Given(/^The Flow page is fully loaded$/) do
+ on(FlowPage).new_topic_body_element.when_not_visible
+end
+
+Given(/^the talk to author link is not visible$/) do
+ on(FlowPage).usertools_talk_link_element.when_not_visible
+end
+
+When(/^I am viewing Topic page$/) do
+ on(FlowPage).wait_until { @browser.url =~ /Topic/ }
+end
+
+When(/^I click New topic save$/) do
+ on(FlowPage) do |page|
+ page.new_topic_save_element.when_present.click
+
+ # Wait for the save to finish, at which point the button will hide
+ page.new_topic_save_element.when_not_visible(10); # Bug 71476 - Saving a new topic can take >5s on beta labs
+ end
+end
+
+When(/^I click the Delete topic button$/) do
+ on(FlowPage).topic_delete_button_element.when_present.click
+end
+
+When(/^I click the flow creator element$/) do
+ on(FlowPage).author_link_element.click
+end
+
+When(/^I click the Hide topic button$/) do
+ on(FlowPage).topic_hide_button_element.when_present.click
+end
+
+When(/^I click the Post Actions link$/) do
+ on(FlowPage).post_actions_link_element.when_present.click
+end
+
+When(/^I click the Suppress topic button$/) do
+ on(FlowPage).topic_suppress_button_element.when_present.click
+end
+
+When(/^I click the Topic Actions link$/) do
+ on(FlowPage).topic_actions_link_element.when_present.click
+end
+
+When(/^I hover over the author link$/) do
+ on(FlowPage).author_link_element.hover
+end
+
+When(/^I see a flow creator element$/) do
+ on(FlowPage).author_link_element.should be_visible
+end
+
+When(/^I type "(.+)" into the new topic content field$/) do |flow_body|
+ body_string = flow_body + @random_string + @automated_test_marker
+ on(FlowPage).new_topic_body_element.when_present.send_keys(body_string)
+end
+
+When(/^I type "(.+)" into the new topic title field$/) do |flow_title|
+ @automated_test_marker = " browsertest edit"
+ on(FlowPage) do |page|
+ @topic_string = flow_title + @random_string + @automated_test_marker
+ page.new_topic_title_element.when_present.click
+ page.new_topic_title_element.when_present.focus
+ page.new_topic_title_element.when_present.send_keys(@topic_string)
+ end
+end
+
+Then(/^I am on my user page$/) do
+ # Get the title of the page without '_' characters
+ text = 'User:' + ENV["MEDIAWIKI_USER"].gsub(/_/, ' ')
+ expect(on(UserPage).first_heading_element.text).to match(text)
+end
+
+Then(/^I should see a Delete button$/) do
+ expect(on(FlowPage).delete_button_element).to be_visible
+end
+
+Then(/^I should see a Delete topic button$/) do
+ expect(on(FlowPage).topic_delete_button_element.when_present).to be_visible
+end
+
+Then(/^I should see a Hide button$/) do
+ expect(on(FlowPage).hide_button_element.when_present).to be_visible
+end
+
+Then(/^I should see a Hide topic button$/) do
+ expect(on(FlowPage).topic_hide_button_element.when_present).to be_visible
+end
+
+Then(/^I should see a Suppress button$/) do
+ expect(on(FlowPage).suppress_button_element).to be_visible
+end
+
+Then(/^I should see a Suppress topic button$/) do
+ expect(on(FlowPage).topic_suppress_button_element.when_present).to be_visible
+end
+
+Then(/^the block author link should not be visible$/) do
+ expect(on(FlowPage).usertools_block_user_link_element).not_to be_visible
+end
+
+Then(/^the block author link should be visible$/) do
+ expect(on(FlowPage).usertools_block_user_link_element.when_present).to be_visible
+end
+
+Then(/^the content of the top post should be visible$/) do
+ expect(on(FlowPage).flow_first_topic_body_element.when_present).to be_visible
+end
+
+Then(/^the content of the top post should not be visible$/) do
+ expect(on(FlowPage).flow_first_topic_body_element).not_to be_visible
+end
+
+Then(/^the Save New Topic button should be disabled$/) do
+ val = on(FlowPage).new_topic_save_element.attribute("disabled")
+ expect(val).to eq("true")
+end
+
+Then(/^the talk to author link should be visible$/) do
+ expect(on(FlowPage).usertools_talk_link_element.when_present).to be_visible
+end
+
+Then(/^the top post should have a heading which contains "(.+)"$/) do |text|
+ on(FlowPage) do |page|
+ page.flow_first_topic_heading_element.when_present
+ expect(page.flow_first_topic_heading).to match(text)
+ end
+end
+
+Then(/^the top post should have content which contains "(.+)"$/) do |text|
+ expect(on(FlowPage).flow_first_topic_body).to match(text)
+end
+
+Then(/^the top post should not have a heading which contains "(.+)"$/) do |text|
+ expect(on(FlowPage).flow_first_topic_heading).not_to match(text)
+end
diff --git a/Flow/tests/browser/features/step_definitions/lock_unlock_topics_steps.rb b/Flow/tests/browser/features/step_definitions/lock_unlock_topics_steps.rb
new file mode 100644
index 00000000..787170f2
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/lock_unlock_topics_steps.rb
@@ -0,0 +1,75 @@
+Given(/^I click the Lock topic button$/) do
+ on(FlowPage) do |page|
+ page.topic_lock_button_element.when_present.focus
+ page.topic_lock_button_element.click
+ end
+end
+
+Given(/^I click the Unlock topic button$/) do
+ on(FlowPage) do |page|
+ page.topic_unlock_button_element.when_present.focus
+ page.topic_unlock_button_element.click
+ end
+end
+
+Given(/^the top post has been locked$/) do
+ step 'I click the Topic Actions link'
+ step 'I click the Lock topic button'
+ step 'I type "This is a bikeshed" as the reason'
+ step 'I submit the lock/unlock topic form'
+end
+
+When(/^I cancel the lock\/unlock topic form$/) do
+ on(FlowPage).topic_lock_form_cancel_button_element.when_present.click
+end
+
+When(/^I expand the top post$/) do
+ on(FlowPage).flow_first_topic_heading_element.when_present.click
+end
+
+When(/^I submit the lock\/unlock topic form$/) do
+ on(FlowPage) do |page|
+ page.topic_lock_form_lock_button_element.when_present.click
+ page.topic_lock_form_lock_button_element.when_not_present
+ end
+end
+
+When(/^I type "(.*?)" as the reason$/) do |reason|
+ on(FlowPage) do |page|
+ page.topic_lock_form_reason_element.when_present.clear
+ # Focus textarea so that any menus that have been clicked lose their focus. In Chrome these might disrupt the test as
+ # elements may be masked and not clickable.
+ page.topic_lock_form_reason_element.click
+ page.topic_lock_form_reason_element.send_keys(reason)
+ end
+end
+
+Then(/^I should not see the lock\/unlock form$/) do
+ on(FlowPage) do |page|
+ page.topic_lock_form_element.when_not_present
+ expect(page.topic_lock_form_element).not_to be_visible
+ end
+end
+
+Then(/the original message for the top post should have no edit link$/) do
+ expect(on(FlowPage).flow_first_topic_original_post_edit_element).not_to be_visible
+end
+
+Then(/^the original message for the top post should have no reply link$/) do
+ expect(on(FlowPage).flow_first_topic_original_post_reply_element).not_to be_visible
+end
+
+Then(/^the reason of the first topic should be "(.*?)"$/) do |text|
+ expect(on(FlowPage).flow_reason_element.text).to match text
+end
+
+Then(/^the top post should be a locked discussion$/) do
+ expect(on(FlowPage).flow_first_topic_moderation_msg_element.when_present).to be_visible
+end
+
+Then(/^the top post should be an open discussion$/) do
+ on(FlowPage) do |page|
+ page.flow_first_topic_moderation_msg_element.when_not_present
+ expect(page.flow_first_topic_moderation_msg_element).not_to be_visible
+ end
+end
diff --git a/Flow/tests/browser/features/step_definitions/moderation_steps.rb b/Flow/tests/browser/features/step_definitions/moderation_steps.rb
new file mode 100644
index 00000000..c6421164
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/moderation_steps.rb
@@ -0,0 +1,47 @@
+When(/^I cancel the dialog$/) do
+ on(FlowPage).dialog_cancel_element.when_present.click
+end
+
+When(/^I click Delete topic$/) do
+ on(FlowPage).dialog_submit_delete_element.when_present.click
+end
+
+When(/^I click Hide topic$/) do
+ on(FlowPage).dialog_submit_hide_element.when_present.click
+end
+
+When(/^I click Suppress topic$/) do
+ on(FlowPage).dialog_submit_suppress_element.when_present.click
+end
+
+When(/^I give reason for deletion as being "(.*?)"$/) do |delete_reason|
+ on(FlowPage).dialog_input_element.when_present.send_keys(delete_reason)
+end
+
+When(/^I give reason for hiding as being "(.*?)"$/) do |hide_reason|
+ on(FlowPage).dialog_input_element.when_present.send_keys(hide_reason)
+end
+
+When(/^I give reason for suppression as being "(.*?)"$/) do |suppress_reason|
+ on(FlowPage).dialog_input_element.when_present.send_keys(suppress_reason)
+end
+
+When(/^I see a dialog box$/) do
+ on(FlowPage).dialog_element.when_present
+end
+
+Then(/^I confirm$/) do
+ on(FlowPage).confirm(true) {}
+end
+
+Then(/^I do not see the dialog box$/) do
+ on(FlowPage).dialog_element.when_not_present
+end
+
+Then(/^the top post should be marked as deleted$/) do
+ expect(on(FlowPage).flow_first_topic_moderation_msg_element.when_present.text).to match("This topic has been deleted")
+end
+
+Then(/^the top post should be marked as suppressed$/) do
+ expect(on(FlowPage).flow_first_topic_moderation_msg_element.when_present.text).to match("This topic has been suppressed")
+end
diff --git a/Flow/tests/browser/features/step_definitions/reply_moderation_steps.rb b/Flow/tests/browser/features/step_definitions/reply_moderation_steps.rb
new file mode 100644
index 00000000..b9f607f6
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/reply_moderation_steps.rb
@@ -0,0 +1,24 @@
+When(/^I click Hide comment button$/) do
+ on(FlowPage) do |page|
+ page.actions_link_hide_3rd_comment_element.when_present.focus
+ page.actions_link_hide_3rd_comment_element.click
+ end
+end
+
+When(/^I click the Hide button in the dialog$/) do
+ on(FlowPage) do |page|
+ page.dialog_submit_hide_element.click
+ page.dialog_submit_hide_element.when_not_present
+ end
+end
+
+Then(/^the 3rd comment should be marked as hidden$/) do
+ on(FlowPage) do |page|
+ page.third_reply_element.when_present
+ expect(page.third_reply_moderation_msg).to match('This comment was hidden')
+ end
+end
+
+Then(/^the content of the 3rd comment should not be visible$/) do
+ expect(on(FlowPage).third_reply_content_element).not_to be_visible
+end
diff --git a/Flow/tests/browser/features/step_definitions/reply_steps.rb b/Flow/tests/browser/features/step_definitions/reply_steps.rb
new file mode 100644
index 00000000..857b6876
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/reply_steps.rb
@@ -0,0 +1,65 @@
+Given(/^I am not watching my new Flow topic$/) do
+ on(FlowPage) do |page|
+ page.first_topic_unwatch_link_element.when_present.click
+ page.first_topic_unwatch_link_element.when_not_visible
+ end
+end
+
+When(/^I click the Cancel button and confirm the dialog$/) do
+ on(FlowPage) do |page|
+ page.confirm(true) do
+ page.new_reply_cancel_element.when_present.click
+ end
+ end
+end
+
+When(/^I click the Keep editing button$/) do
+ on(FlowPage) do |page|
+ page.keep_editing_element.when_present.click
+ # Keep editing returns to the Preview button.
+ page.wait_until { page.new_reply_preview_element.visible? }
+ end
+end
+
+When(/^I click the Preview button$/) do
+ on(FlowPage) do |page|
+ page.new_reply_preview_element.when_present.click
+ page.wait_until { page.preview_warning_element.visible? }
+ end
+end
+
+When(/^I reply with comment "(.*?)"$/) do |content|
+ on(FlowPage) do |page|
+ page.new_reply_save_element.when_not_present
+ page.new_reply_input_element.when_present.click
+ page.new_reply_input_element.send_keys(content)
+ page.new_reply_save_element.when_present.click
+ page.new_reply_save_element.when_not_present
+ end
+end
+
+When(/^I start a reply with comment "(.*?)"$/) do |content|
+ on(FlowPage) do |page|
+ page.new_reply_save_element.when_not_present
+ page.new_reply_input_element.when_present.click
+ page.new_reply_input_element.send_keys(content)
+ end
+end
+
+Then(/^I should see an unwatch link on the topic$/) do
+ expect(on(FlowPage).first_topic_unwatch_link_element).to be_visible
+end
+
+Then(/^the top post's first reply should contain the text "(.+)"$/) do |text|
+ on(FlowPage) do |page|
+ page.new_reply_save_element.when_not_present
+ expect(page.first_reply_body).to match(text)
+ end
+end
+
+Then(/^I should see the topic reply form$/) do
+ on(FlowPage) do |page|
+ page.wait_until { page.new_reply_input_element.visible? }
+ expect(page.new_reply_input_element).to be_visible
+ end
+end
diff --git a/Flow/tests/browser/features/step_definitions/sorting_topics_steps.rb b/Flow/tests/browser/features/step_definitions/sorting_topics_steps.rb
new file mode 100644
index 00000000..eb8b18bf
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/sorting_topics_steps.rb
@@ -0,0 +1,34 @@
+When(/^I click Newest topics choice$/) do
+ on(FlowPage).newest_topics_choice_element.when_present.click
+end
+
+When(/^I click Newest topics link$/) do
+ on(FlowPage).newest_topics_link_element.when_present.click
+end
+
+When(/^I click Recently active topics choice$/) do
+ on(FlowPage).recently_active_topics_choice_element.when_present.click
+end
+
+When(/^I click Recently active topics link$/) do
+ on(FlowPage) do |page|
+ page.recently_active_topics_choice_element.when_not_visible
+ page.recently_active_topics_link_element.when_present.click
+ end
+end
+
+Then(/^the Flow page should not show Recently active topics link$/) do
+ expect(on(FlowPage).recently_active_topics_link_element.when_not_visible).not_to be_visible
+end
+
+Then(/^the Flow page should show Recently active topics link$/) do
+ expect(on(FlowPage).recently_active_topics_link_element.when_present).to be_visible
+end
+
+Then(/^the Flow page should not show Newest topics link$/) do
+ expect(on(FlowPage).newest_topics_link_element.when_not_visible).not_to be_visible
+end
+
+Then(/^the Flow page should show Newest topics link$/) do
+ expect(on(FlowPage).newest_topics_link_element.when_present).to be_visible
+end
diff --git a/Flow/tests/browser/features/step_definitions/thank_steps.rb b/Flow/tests/browser/features/step_definitions/thank_steps.rb
new file mode 100644
index 00000000..d448258e
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/thank_steps.rb
@@ -0,0 +1,37 @@
+Given(/^the "(.*?)" page has a new unmoderated topic created by me$/) do |title|
+ client = on(APIPage).client
+ client.log_in(ENV["MEDIAWIKI_USER"], ENV["MEDIAWIKI_PASSWORD"])
+ client.action('flow', token_type: 'edit', submodule: 'new-topic', page: title, nttopic: 'Thank me please!', ntcontent: 'Hello')
+end
+
+Given(/^the most recent topic on "(.*?)" is written by another user$/) do |title|
+ client = on(APIPage).client
+ username = 'Selenium Flow user 2'
+ begin
+ client.create_account(username, ENV["MEDIAWIKI_PASSWORD"])
+ rescue MediawikiApi::ApiError
+ puts 'Assuming user ' + username + ' already exists since was unable to create.'
+ end
+
+ client.log_in(username, ENV["MEDIAWIKI_PASSWORD"])
+ client.action('flow', token_type: 'edit', submodule: 'new-topic', page: title, nttopic: 'Thank me please!', ntcontent: 'Hello')
+end
+
+When(/^I click on the Thank button$/) do
+ on(FlowPage).thank_button_element.click
+end
+
+When(/^I see a Thank button$/) do
+ on(FlowPage).thank_button_element.when_present
+end
+
+Then(/^I should not see a Thank button$/) do
+ expect(on(FlowPage).thank_button_element).not_to be_visible
+end
+
+Then(/^I should see the Thank button be replaced with Thanked button$/) do
+ on(FlowPage) do |page|
+ expect(page.thanked_button_element.when_present).to be_visible
+ expect(page.thank_button_element).not_to be_visible
+ end
+end
diff --git a/Flow/tests/browser/features/step_definitions/watch_steps.rb b/Flow/tests/browser/features/step_definitions/watch_steps.rb
new file mode 100644
index 00000000..57ca38a4
--- /dev/null
+++ b/Flow/tests/browser/features/step_definitions/watch_steps.rb
@@ -0,0 +1,64 @@
+Given(/^I am not watching the Flow board$/) do
+ on(FlowPage) do |page|
+ page.board_unwatch_link_element.when_present.click unless page.board_watch_link_element.visible?
+ end
+end
+
+Given(/^I am not watching the Flow topic$/) do
+ on(FlowPage).first_topic_unwatch_link_element.when_present.click
+end
+
+Given(/^I am watching the Flow topic$/) do
+ on(FlowPage).first_topic_unwatch_link_element.when_present
+end
+
+Given(/^I am watching the Flow board$/) do
+ on(FlowPage) do |page|
+ page.board_watch_link_element.when_present.click unless page.board_unwatch_link_element.visible?
+ end
+end
+
+When(/^I click the Unwatch Board link$/) do
+ on(FlowPage).board_unwatch_link_element.when_present.click
+end
+
+When(/^I click the Unwatch Topic link$/) do
+ on(FlowPage).first_topic_unwatch_link_element.when_present.click
+end
+
+When(/^I click the Watch Board link$/) do
+ on(FlowPage).board_watch_link_element.when_present.click
+end
+
+When(/^I click the Watch Topic link$/) do
+ on(FlowPage).first_topic_watch_link_element.when_present.click
+end
+
+Then(/^I should see the Unwatch Topic link$/) do
+ expect(on(FlowPage).first_topic_unwatch_link_element.when_present).to be_visible
+end
+
+Then(/^I should not see any watch links$/) do
+ on(FlowPage) do |page|
+ expect(page.board_watch_link_element).not_to be_visible
+ expect(page.first_topic_watch_link_element).not_to be_visible
+ end
+end
+
+Then(/^I should see the Unwatch Board link$/) do
+ on(FlowPage) do |page|
+ page.board_watch_link_element.when_not_visible
+ expect(page.board_unwatch_link_element).to be_visible
+ end
+end
+
+Then(/^I should see the Watch Board link$/) do
+ expect(on(FlowPage).board_watch_link_element.when_present).to be_visible
+end
+
+Then(/^I should see the Watch Topic link$/) do
+ on(FlowPage) do |page|
+ page.first_topic_unwatch_link_element.when_not_visible
+ expect(page.first_topic_watch_link_element).to be_visible
+ end
+end
diff --git a/Flow/tests/browser/features/support/env.rb b/Flow/tests/browser/features/support/env.rb
new file mode 100644
index 00000000..55b30cef
--- /dev/null
+++ b/Flow/tests/browser/features/support/env.rb
@@ -0,0 +1,10 @@
+require "mediawiki_api"
+require "mediawiki_selenium"
+
+if ENV['PAGE_WAIT_TIMEOUT']
+ PageObject.default_page_wait = ENV['PAGE_WAIT_TIMEOUT'].to_i
+end
+
+if ENV['ELEMENT_WAIT_TIMEOUT']
+ PageObject.default_element_wait = ENV['ELEMENT_WAIT_TIMEOUT'].to_i
+end
diff --git a/Flow/tests/browser/features/support/hooks.rb b/Flow/tests/browser/features/support/hooks.rb
new file mode 100644
index 00000000..5ab6259d
--- /dev/null
+++ b/Flow/tests/browser/features/support/hooks.rb
@@ -0,0 +1,3 @@
+# Allow running of bundle exec cucumber --dry-run -f stepdefs
+require "mediawiki_selenium"
+require 'page-object'
diff --git a/Flow/tests/browser/features/support/pages/flow_old_permalink_page.rb b/Flow/tests/browser/features/support/pages/flow_old_permalink_page.rb
new file mode 100644
index 00000000..d550a27b
--- /dev/null
+++ b/Flow/tests/browser/features/support/pages/flow_old_permalink_page.rb
@@ -0,0 +1,7 @@
+class FlowOldPermalinkPage
+ include PageObject
+ include URL
+
+ @params = { page: 'Talk:Flow QA', workflow_id: 'no workflow' }
+ page_url URL.url(params[:page]) + "?workflow=<%=params[:workflow_id]%>"
+end
diff --git a/Flow/tests/browser/features/support/pages/flow_page.rb b/Flow/tests/browser/features/support/pages/flow_page.rb
new file mode 100644
index 00000000..4a052247
--- /dev/null
+++ b/Flow/tests/browser/features/support/pages/flow_page.rb
@@ -0,0 +1,239 @@
+class WikiPage
+ include PageObject
+ a(:logout, css: "#pt-logout a")
+end
+
+class FlowPage < WikiPage
+ include URL
+ # MEDIAWIKI_URL must have this in $wgFlowOccupyPages array or $wgFlowOccupyNamespaces.
+ page_url URL.url("Talk:Flow_QA")
+
+ # board header
+ a(:edit_header_link, title: "Edit header")
+ div(:header_content, css: ".flow-board-header-detail-view p", index: 0)
+ form(:edit_header_form, css: ".flow-board-header-edit-view form")
+ textarea(:edit_header_textbox, css: ".flow-board-header-edit-view textarea")
+
+ a(:author_link, css: ".flow-author a", index: 0)
+ a(:cancel_button, text: "Cancel")
+
+ # XXX (mattflaschen, 2014-06-24): This is broken; there is no
+ # flow-topic-reply-form anywhere in Flow outside this file.
+ # Also, this should be named to distinguish between top-level posts and regular replies.
+ textarea(:comment_field, css: 'form.flow-topic-reply-form > textarea[name="topic_content"]')
+ button(:comment_reply_save, css: "form.flow-topic-reply-form .flow-reply-submit")
+ div(:flow_topics, class: "flow-topics")
+
+ # Dialogs
+ div(:dialog, css: ".flow-ui-modal")
+ textarea(:dialog_input, name: "topic_reason")
+ button(:dialog_cancel, css: "a.mw-ui-destructive:nth-child(2)")
+ button(:dialog_submit_delete, text: "Delete")
+ button(:dialog_submit_hide, text: "Hide")
+ button(:dialog_submit_suppress, text: "Suppress")
+
+ # Posts
+ ## Highlighted post
+ div(:highlighted_post, css: ".flow-post-highlighted")
+
+ ## First topic
+ div(:flow_first_topic, css: ".flow-topic", index: 0)
+ h2(:flow_first_topic_heading, css: ".flow-topic h2", index: 0)
+ # todo this is poor naming, it's really the first_topic_first_post_content
+ div(:flow_first_topic_body, css: ".flow-topic .flow-post-content", index: 0)
+ div(:flow_first_topic_moderation_msg) do |page|
+ page.flow_first_topic_element.div_element(css: "div.flow-topic-titlebar div.flow-moderated-topic-title")
+ end
+
+ div(:flow_first_topic_summary) do |page|
+ page.flow_first_topic_element.div_element(css: ".flow-topic-summary")
+ end
+ div(:flow_first_topic_original_post, css: ".flow-post", index: 0)
+ a(:flow_first_topic_original_post_edit) do |page|
+ page.flow_first_topic_original_post_element.link_element(text: "Edit")
+ end
+ a(:flow_first_topic_original_post_reply) do |page|
+ page.flow_first_topic_original_post_element.link_element(text: "Reply")
+ end
+ div(:flow_second_topic_heading, css: ".flow-topic", index: 1)
+
+ ### Hover over username behaviour
+ span(:usertools, css: '.mw-usertoollinks')
+ a(:usertools_talk_link) do |page|
+ page.usertools_element.link_element(text: 'Talk')
+ end
+ a(:usertools_block_user_link) do |page|
+ page.usertools_element.link_element(text: 'block')
+ end
+
+ ### First Topic actions menu
+
+ # For topic collapsing testing
+ # Works around CSS descendant selector problem (https://github.com/cheezy/page-object/issues/222)
+ div(:first_moderated_topic, css: '.flow-topic.flow-topic-moderated', index: 0)
+
+ div(:first_moderated_topic_titlebar) do |page|
+ page.first_moderated_topic_element.div_element(css: '.flow-topic-titlebar')
+ end
+
+ div(:first_moderated_message) do |page|
+ page.first_moderated_topic_titlebar_element.div_element(css: '.flow-moderated-topic-title')
+ end
+
+ h2(:first_moderated_topic_title) do |page|
+ page.first_moderated_topic_titlebar_element.h2_element(class: 'flow-topic-title')
+ end
+
+ div(:first_moderated_topic_post_content) do |page|
+ page.first_moderated_topic_element.div_element(class: 'flow-post', index: 0).div_element(class: 'flow-post-main').div_element(class: 'flow-post-content')
+ end
+
+ # Topic actions menu (all belonging to the first post)
+ a(:topic_actions_link, css: ".flow-topic .flow-topic-titlebar .flow-menu-js-drop a", index: 0)
+ ul(:topic_actions_menu, css: ".flow-topic .flow-topic-titlebar .flow-menu ul", index: 0)
+ a(:topic_hide_button) do |page|
+ page.topic_actions_menu_element.link_element(text: "Hide topic")
+ end
+ a(:topic_delete_button) do |page|
+ page.topic_actions_menu_element.link_element(text: "Delete topic")
+ end
+ a(:topic_suppress_button) do |page|
+ page.topic_actions_menu_element.link_element(text: "Suppress topic")
+ end
+ a(:permalink_button) do |page|
+ page.topic_actions_menu_element.link_element(text: "Permalink")
+ end
+ a(:edit_title_button) do |page|
+ page.topic_actions_menu_element.link_element(text: "Edit title")
+ end
+ a(:topic_lock_button) do |page|
+ page.topic_actions_menu_element.link_element(title: "Lock topic")
+ end
+ a(:topic_unlock_button) do |page|
+ page.topic_actions_menu_element.link_element(title: "Unlock topic")
+ end
+
+ ## Lock topic workflow
+ form(:topic_lock_form, css: ".flow-edit-form")
+ textarea(:topic_lock_form_reason, css: ".flow-edit-form textarea")
+ button(:topic_lock_form_lock_button, css: ".flow-edit-form .mw-ui-constructive")
+ button(:topic_lock_form_cancel_button, css: ".flow-edit-form .mw-ui-destructive")
+ div(:flow_reason, class: "flow-moderated-topic-reason")
+
+ ### Editing title of first topic
+ text_field(:title_edit, css: ".flow-topic-titlebar form .mw-ui-input", index: 0)
+ button(:change_title_save, css: ".flow-topic-titlebar form .mw-ui-constructive")
+
+ ### Post meta actions
+ span(:post_meta_actions, css: ".flow-post .flow-post-meta-actions", index: 0)
+ a(:edit_post) do |page|
+ page.post_meta_actions_element.link_element(title: "Edit")
+ end
+ a(:thank_button) do |page|
+ page.post_meta_actions_element.link_element(css: ".mw-thanks-flow-thank-link", index: 0)
+ end
+ span(:thanked_button) do |page|
+ page.post_meta_actions_element.span_element(css: ".mw-thanks-flow-thanked", index: 0)
+ end
+
+ ### First post of first topic actions menu
+ a(:post_actions_link, css: ".flow-topic .flow-post .flow-menu-js-drop a", index: 0)
+ ul(:post_actions_menu, css: ".flow-topic .flow-post .flow-menu ul", index: 0)
+ a(:hide_button) do |page|
+ page.post_actions_menu_element.link_element(title: "Hide")
+ end
+ a(:delete_button) do |page|
+ page.post_actions_menu_element.link_element(title: "Delete")
+ end
+ a(:suppress_button) do |page|
+ page.post_actions_menu_element.link_element(title: "Suppress")
+ end
+
+ ### Replies to top post
+ #### 1st reply
+ # @todo: This is broken. It should be clearly possible to distinguish between the top reply and
+ # the top post. There is an element .flow-replies which appears to be empty.
+ div(:first_reply, css: '.flow-post', index: 1)
+ div(:first_reply_body) do |page|
+ page.first_reply_element.div_element(css: '.flow-post-content')
+ end
+
+ #### 3rd reply
+ # @todo: Should be index: 2, but sadly no way to distinguish replies from original post
+ div(:third_reply, css: '.flow-post', index: 3)
+ div(:third_reply_moderation_msg) do |page|
+ page.third_reply_element.span_element(css: '.flow-moderated-post-content', index: 0)
+ end
+ div(:third_reply_content) do |page|
+ page.third_reply_element.div_element(css: '.flow-post-content', index: 0)
+ end
+
+ a(:third_post_actions_link, css: ".flow-topic .flow-post .flow-menu-js-drop a", index: 3)
+ ul(:third_post_actions_menu, css: ".flow-topic .flow-post .flow-menu ul", index: 3)
+ a(:actions_link_permalink_3rd_comment) do |page|
+ page.third_post_actions_menu_element.link_element(text: "Permalink")
+ end
+ a(:actions_link_hide_3rd_comment) do |page|
+ page.third_post_actions_menu_element.link_element(text: "Hide")
+ end
+
+ # New topic creation
+ form(:new_topic_form, css: ".flow-newtopic-form")
+ text_field(:new_topic_title, name: "topiclist_topic")
+ textarea(:new_topic_body, name: "topiclist_content")
+ button(:new_topic_cancel, css: ".flow-newtopic-form .mw-ui-destructive")
+ button(:new_topic_preview, css: ".flow-newtopic-form .mw-ui-progressive")
+ # FIXME: Remove flow-ui-constructive reference when cache has cleared
+ button(:new_topic_save, css: ".flow-newtopic-form .mw-ui-constructive, .flow-newtopic-form .flow-ui-constructive")
+
+ # Replying
+ # TODO (mattflaschen, 2014-06-24): Should distinguish between
+ # top-level replies to the topic, and replies to regular posts
+ form(:new_reply_form, css: ".flow-reply-form")
+ # Is an input when not focused, textarea when focused
+ textarea(:new_reply_input, css: ".flow-reply-form .mw-ui-input")
+ button(:new_reply_cancel, css: ".flow-reply-form .mw-ui-destructive")
+ button(:new_reply_preview, css: ".flow-reply-form .mw-ui-progressive")
+ button(:new_reply_save, css: ".flow-reply-form .mw-ui-constructive")
+ button(:keep_editing, text: "Keep editing")
+ div(:preview_warning, css: ".flow-preview-warning")
+
+ # Editing post workflow
+ text_area(:post_edit, css: ".flow-edit-post-form textarea")
+ button(:change_post_save, css: ".flow-edit-post-form .mw-ui-constructive")
+
+ button(:preview_button, class: "mw-ui-button flow-preview-submit")
+ div(:small_spinner, class: "mw-spinner mw-spinner-small mw-spinner-inline")
+
+ button(:edit_header_save, text: "Save header")
+
+ # No javascript elements
+ button(:no_javascript_add_topic, text: "Add topic")
+ div(:no_javascript_page_content_body, class: "flow-post-content")
+ div(:no_javascript_page_content_title, class: "flow-topic-titlebar")
+ div(:no_javascript_page_flow_topics, class: "flow-topics")
+ button(:no_javascript_reply, text: "Reply")
+ textarea(:no_javascript_reply_form, name: "topic_content")
+ a(:no_javascript_start_reply, href: /action=reply/)
+ a(:no_javascript_start_topic, href: /action=new-topic/)
+ textarea(:no_javascript_topic_body_text, name: "topiclist_content")
+ text_field(:no_javascript_topic_title_text, name: "topiclist_topic")
+
+ # Sorting
+ a(:newest_topics_link, text: "Newest topics")
+ a(:recently_active_topics_choice, href: /topiclist_sortby=updated/)
+ a(:recently_active_topics_link, text: "Recently active topics")
+ a(:newest_topics_choice, href: /topiclist_sortby=newest/)
+
+ ## Watch and unwatch links
+ div(:first_topic_watchlist_container, css: ".flow-topic-watchlist", index: 0)
+ a(:first_topic_watch_link) do |page|
+ page.first_topic_watchlist_container_element.link_element(css: ".flow-watch-link-watch")
+ end
+ a(:first_topic_unwatch_link) do |page|
+ page.first_topic_watchlist_container_element.link_element(css: ".flow-watch-link-unwatch")
+ end
+
+ a(:board_unwatch_link, href: /Flow_QA&action=unwatch/)
+ a(:board_watch_link, href: /Flow_QA&action=watch/)
+end
diff --git a/Flow/tests/browser/features/support/pages/new_flow_page.rb b/Flow/tests/browser/features/support/pages/new_flow_page.rb
new file mode 100644
index 00000000..16ed9c6e
--- /dev/null
+++ b/Flow/tests/browser/features/support/pages/new_flow_page.rb
@@ -0,0 +1,7 @@
+require "page-object"
+
+class NewFlowPage < FlowPage
+ include URL
+ # MEDIAWIKI_URL must have User_talk in $wgFlowOccupyNamespaces.
+ page_url URL.url("User_talk:New page " + Array.new(8) { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join)
+end
diff --git a/Flow/tests/browser/features/support/pages/recent_changes_page.rb b/Flow/tests/browser/features/support/pages/recent_changes_page.rb
new file mode 100644
index 00000000..5941295b
--- /dev/null
+++ b/Flow/tests/browser/features/support/pages/recent_changes_page.rb
@@ -0,0 +1,8 @@
+class RecentChangesPage
+ include PageObject
+
+ include URL
+ page_url URL.url('Special:RecentChanges')
+
+ div(:recent_changes, class: 'mw-changeslist')
+end
diff --git a/Flow/tests/browser/features/support/pages/user_page.rb b/Flow/tests/browser/features/support/pages/user_page.rb
new file mode 100644
index 00000000..baf8b769
--- /dev/null
+++ b/Flow/tests/browser/features/support/pages/user_page.rb
@@ -0,0 +1,9 @@
+class UserPage
+ include PageObject
+
+ include URL
+ # MEDIAWIKI_URL must have this in $wgFlowOccupyPages array or $wgFlowOccupyNamespaces.
+ page_url URL.url("User talk:ENV['MEDIAWIKI_USER']")
+
+ h1(:first_heading, id: "firstHeading")
+end
diff --git a/Flow/tests/browser/features/thank.feature b/Flow/tests/browser/features/thank.feature
new file mode 100644
index 00000000..a3479223
--- /dev/null
+++ b/Flow/tests/browser/features/thank.feature
@@ -0,0 +1,23 @@
+@chrome @clean @en.wikipedia.beta.wmflabs.org @firefox @internet_explorer_10 @login @test2.wikipedia.org
+Feature: Thank author of a Flow post
+
+ Scenario: Anon does not see Thank button
+ Given the "Talk:Flow QA" page has a new unmoderated topic created by me
+ And I am on Flow page
+ Then I should not see a Thank button
+
+ @login
+ Scenario: Thank the user
+ Given I am logged in
+ And the most recent topic on "Talk:Flow QA" is written by another user
+ And I am on Flow page
+ And I see a Thank button
+ When I click on the Thank button
+ Then I should see the Thank button be replaced with Thanked button
+
+ @login
+ Scenario: I cannot thank my own post
+ Given I am logged in
+ And the "Talk:Flow QA" page has a new unmoderated topic created by me
+ And I am on Flow page
+ Then I should not see a Thank button
diff --git a/Flow/tests/browser/features/watch.feature b/Flow/tests/browser/features/watch.feature
new file mode 100644
index 00000000..b7460834
--- /dev/null
+++ b/Flow/tests/browser/features/watch.feature
@@ -0,0 +1,36 @@
+@test2.wikipedia.org @en.wikipedia.beta.wmflabs.org @phantomjs
+Feature: Watching/Unwatching Boards and Topics
+
+ Scenario: Watch topic
+ Given I am logged in
+ And I am on Flow page
+ And I have created a Flow topic
+ And I am not watching the Flow topic
+ When I click the Watch Topic link
+ Then I should see the Unwatch Topic link
+
+ Scenario: Unwatch topic
+ Given I am logged in
+ And I am on Flow page
+ And I have created a Flow topic
+ And I am watching the Flow topic
+ When I click the Unwatch Topic link
+ Then I should see the Watch Topic link
+
+ Scenario: Watch board
+ Given I am logged in
+ And I am on Flow page
+ And I am not watching the Flow board
+ When I click the Watch Board link
+ Then I should see the Unwatch Board link
+
+ Scenario: Unwatch board
+ Given I am logged in
+ And I am on Flow page
+ And I am watching the Flow board
+ When I click the Unwatch Board link
+ Then I should see the Watch Board link
+
+ Scenario: No watch links for anonymous users
+ When I am on Flow page
+ Then I should not see any watch links