From 1da118780e3edb611c245819435c4149ba497119 Mon Sep 17 00:00:00 2001 From: lislis Date: Sun, 28 Apr 2019 19:06:48 +0200 Subject: Two factor authentication (#7751) --- features/desktop/change_password.feature | 3 +- features/desktop/two_factor_authentication.feature | 90 ++++++++++++++++++++++ features/mobile/change_password.feature | 5 +- features/step_definitions/two_factor_steps.rb | 67 ++++++++++++++++ features/support/paths.rb | 2 + 5 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 features/desktop/two_factor_authentication.feature create mode 100644 features/step_definitions/two_factor_steps.rb (limited to 'features') diff --git a/features/desktop/change_password.feature b/features/desktop/change_password.feature index f37ebe045..7b30014ec 100644 --- a/features/desktop/change_password.feature +++ b/features/desktop/change_password.feature @@ -29,8 +29,7 @@ Feature: Change password When I follow the "Change my password" link from the last sent email When I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form - Then I should be on the stream page - And I sign out manually + Then I should be on the new user session page And I sign in manually as "georges_abitbol" with password "supersecret" Then I should be on the stream page diff --git a/features/desktop/two_factor_authentication.feature b/features/desktop/two_factor_authentication.feature new file mode 100644 index 000000000..ae8e2d2ef --- /dev/null +++ b/features/desktop/two_factor_authentication.feature @@ -0,0 +1,90 @@ +# frozen_string_literal: true +@javascript +Feature: Two-factor autentication + + Scenario: Activate 2fa + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + When I go to the two-factor authentication page + And I press "Activate" + Then I should see "Confirm activation" + When I scan the QR code and fill in a valid TOTP token for "alice@test.com" + And I press "Confirm and activate" + Then I should see "Two-factor authentication activated" + And I should see "Recovery codes" + When I confirm activation + Then I should see "Two-factor authentication activated" + And I should see "Deactivate" + + Scenario: Signing in with 2fa activated and correct token + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in a valid TOTP token for "alice" + And I press "Sign in" + Then I should be on the stream page + + Scenario: Trying to sign in with 2fa activated and incorrect token + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in an invalid TOTP token + And I press "Sign in" + Then I should see "Two-factor authentication" + + Scenario: Signing in with 2fa activated and a recovery code + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in a recovery code from "alice" + And I press "Sign in" + Then I should be on the stream page + + Scenario: Regenerating recovery codes + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Generate new recovery codes" + When I press the recovery code generate button + Then I should see a list of recovery codes + + Scenario: Deactivating 2fa with correct token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in a valid TOTP token to deactivate for "alice@test.com" + And I press "Deactivate" + Then I should see "Two-factor authentication not activated" + + Scenario: Deactivating 2fa with recovery token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in a recovery code to deactivate from "alice@test.com" + And I press "Deactivate" + Then I should see "Two-factor authentication not activated" + + Scenario: Trying to deactivate with incorrect token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in an invalid TOTP token to deactivate + And I press "Deactivate" + Then I should see "Two-factor authentication activated" + And I should see "Deactivate" diff --git a/features/mobile/change_password.feature b/features/mobile/change_password.feature index f30edb215..f3bcdb445 100644 --- a/features/mobile/change_password.feature +++ b/features/mobile/change_password.feature @@ -31,9 +31,8 @@ Feature: Change password When I follow the "Change my password" link from the last sent email And I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form - Then I should be on the stream page - When I sign out - And I go to the login page + Then I should be on the new user session page + When I go to the login page And I sign in manually as "georges_abitbol" with password "supersecret" on the mobile website Then I should be on the stream page diff --git a/features/step_definitions/two_factor_steps.rb b/features/step_definitions/two_factor_steps.rb new file mode 100644 index 000000000..7b5ab2319 --- /dev/null +++ b/features/step_definitions/two_factor_steps.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +When /^I scan the QR code and fill in a valid TOTP token for "([^"]*)"$/ do |email| + @me = find_user email + fill_in "user_code", with: @me.current_otp +end + +When /^I fill in a valid TOTP token for "([^"]*)"$/ do |username| + @me = find_user username + fill_in "user_otp_attempt", with: @me.current_otp +end + +When /^I fill in an invalid TOTP token$/ do + fill_in "user_otp_attempt", with: "c0ffee" +end + +When /^I fill in a valid TOTP token to deactivate for "([^"]*)"$/ do |username| + @me = find_user username + fill_in "two_factor_authentication_code", with: @me.current_otp +end + +When /^I fill in an invalid TOTP token to deactivate$/ do + fill_in "two_factor_authentication_code", with: "c0ffee" +end + +When /^I fill in a recovery code from "([^"]*)"$/ do |username| + @me = find_user username + @codes = @me.generate_otp_backup_codes! + @me.save! + fill_in "user_otp_attempt", with: @codes.first +end + +When /^I fill in a recovery code to deactivate from "([^"]*)"$/ do |username| + @me = find_user username + @codes = @me.generate_otp_backup_codes! + @me.save! + fill_in "two_factor_authentication_code", with: @codes.first +end + +When /^I confirm activation$/ do + find(".btn-primary", match: :first).click +end + +When /^2fa is activated for "([^"]*)"$/ do |username| + @me = find_user username + @me.otp_secret = User.generate_otp_secret(32) + @me.otp_required_for_login = true + @me.save! +end + +When /^I fill in username "([^"]*)" and password "([^"]*)"$/ do |username, password| + fill_in "user_username", with: username + fill_in "user_password", with: password +end + +Then /^I should see a list of recovery codes$/ do + find(".recovery-codes", match: :first) + find(".recovery-codes li samp", match: :first) +end + +When /^I press the recovery code generate button$/ do + find(".btn-default", match: :first).click +end + +def find_user(username) + User.find_by(username: username) || User.find_by(email: username) +end diff --git a/features/support/paths.rb b/features/support/paths.rb index a486ef245..7962fe17d 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -40,6 +40,8 @@ module NavigationHelpers edit_user_path when /^forgot password page$/ new_user_password_path + when /^the two-factor authentication page$/ + two_factor_authentication_path when %r{^"(/.*)"} Regexp.last_match(1) else -- cgit v1.2.3 From 9d5b981809435b05b06e300a5495a71085e89882 Mon Sep 17 00:00:00 2001 From: lislis Date: Sun, 28 Apr 2019 19:06:48 +0200 Subject: Two factor authentication (#7751) --- features/desktop/change_password.feature | 3 +- features/desktop/two_factor_authentication.feature | 90 ++++++++++++++++++++++ features/mobile/change_password.feature | 5 +- features/step_definitions/two_factor_steps.rb | 67 ++++++++++++++++ features/support/paths.rb | 2 + 5 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 features/desktop/two_factor_authentication.feature create mode 100644 features/step_definitions/two_factor_steps.rb (limited to 'features') diff --git a/features/desktop/change_password.feature b/features/desktop/change_password.feature index f37ebe045..7b30014ec 100644 --- a/features/desktop/change_password.feature +++ b/features/desktop/change_password.feature @@ -29,8 +29,7 @@ Feature: Change password When I follow the "Change my password" link from the last sent email When I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form - Then I should be on the stream page - And I sign out manually + Then I should be on the new user session page And I sign in manually as "georges_abitbol" with password "supersecret" Then I should be on the stream page diff --git a/features/desktop/two_factor_authentication.feature b/features/desktop/two_factor_authentication.feature new file mode 100644 index 000000000..ae8e2d2ef --- /dev/null +++ b/features/desktop/two_factor_authentication.feature @@ -0,0 +1,90 @@ +# frozen_string_literal: true +@javascript +Feature: Two-factor autentication + + Scenario: Activate 2fa + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + When I go to the two-factor authentication page + And I press "Activate" + Then I should see "Confirm activation" + When I scan the QR code and fill in a valid TOTP token for "alice@test.com" + And I press "Confirm and activate" + Then I should see "Two-factor authentication activated" + And I should see "Recovery codes" + When I confirm activation + Then I should see "Two-factor authentication activated" + And I should see "Deactivate" + + Scenario: Signing in with 2fa activated and correct token + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in a valid TOTP token for "alice" + And I press "Sign in" + Then I should be on the stream page + + Scenario: Trying to sign in with 2fa activated and incorrect token + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in an invalid TOTP token + And I press "Sign in" + Then I should see "Two-factor authentication" + + Scenario: Signing in with 2fa activated and a recovery code + Given a user with username "alice" and password "secret" + And 2fa is activated for "alice" + When I go to the login page + And I fill in username "alice" and password "secret" + And press "Sign in" + Then I should see "Two-factor authentication" + When I fill in a recovery code from "alice" + And I press "Sign in" + Then I should be on the stream page + + Scenario: Regenerating recovery codes + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Generate new recovery codes" + When I press the recovery code generate button + Then I should see a list of recovery codes + + Scenario: Deactivating 2fa with correct token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in a valid TOTP token to deactivate for "alice@test.com" + And I press "Deactivate" + Then I should see "Two-factor authentication not activated" + + Scenario: Deactivating 2fa with recovery token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in a recovery code to deactivate from "alice@test.com" + And I press "Deactivate" + Then I should see "Two-factor authentication not activated" + + Scenario: Trying to deactivate with incorrect token + Given a user with email "alice@test.com" + When I sign in as "alice@test.com" + And 2fa is activated for "alice@test.com" + When I go to the two-factor authentication page + Then I should see "Deactivate" + When I fill in an invalid TOTP token to deactivate + And I press "Deactivate" + Then I should see "Two-factor authentication activated" + And I should see "Deactivate" diff --git a/features/mobile/change_password.feature b/features/mobile/change_password.feature index f30edb215..f3bcdb445 100644 --- a/features/mobile/change_password.feature +++ b/features/mobile/change_password.feature @@ -31,9 +31,8 @@ Feature: Change password When I follow the "Change my password" link from the last sent email And I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form - Then I should be on the stream page - When I sign out - And I go to the login page + Then I should be on the new user session page + When I go to the login page And I sign in manually as "georges_abitbol" with password "supersecret" on the mobile website Then I should be on the stream page diff --git a/features/step_definitions/two_factor_steps.rb b/features/step_definitions/two_factor_steps.rb new file mode 100644 index 000000000..7b5ab2319 --- /dev/null +++ b/features/step_definitions/two_factor_steps.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +When /^I scan the QR code and fill in a valid TOTP token for "([^"]*)"$/ do |email| + @me = find_user email + fill_in "user_code", with: @me.current_otp +end + +When /^I fill in a valid TOTP token for "([^"]*)"$/ do |username| + @me = find_user username + fill_in "user_otp_attempt", with: @me.current_otp +end + +When /^I fill in an invalid TOTP token$/ do + fill_in "user_otp_attempt", with: "c0ffee" +end + +When /^I fill in a valid TOTP token to deactivate for "([^"]*)"$/ do |username| + @me = find_user username + fill_in "two_factor_authentication_code", with: @me.current_otp +end + +When /^I fill in an invalid TOTP token to deactivate$/ do + fill_in "two_factor_authentication_code", with: "c0ffee" +end + +When /^I fill in a recovery code from "([^"]*)"$/ do |username| + @me = find_user username + @codes = @me.generate_otp_backup_codes! + @me.save! + fill_in "user_otp_attempt", with: @codes.first +end + +When /^I fill in a recovery code to deactivate from "([^"]*)"$/ do |username| + @me = find_user username + @codes = @me.generate_otp_backup_codes! + @me.save! + fill_in "two_factor_authentication_code", with: @codes.first +end + +When /^I confirm activation$/ do + find(".btn-primary", match: :first).click +end + +When /^2fa is activated for "([^"]*)"$/ do |username| + @me = find_user username + @me.otp_secret = User.generate_otp_secret(32) + @me.otp_required_for_login = true + @me.save! +end + +When /^I fill in username "([^"]*)" and password "([^"]*)"$/ do |username, password| + fill_in "user_username", with: username + fill_in "user_password", with: password +end + +Then /^I should see a list of recovery codes$/ do + find(".recovery-codes", match: :first) + find(".recovery-codes li samp", match: :first) +end + +When /^I press the recovery code generate button$/ do + find(".btn-default", match: :first).click +end + +def find_user(username) + User.find_by(username: username) || User.find_by(email: username) +end diff --git a/features/support/paths.rb b/features/support/paths.rb index a486ef245..7962fe17d 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -40,6 +40,8 @@ module NavigationHelpers edit_user_path when /^forgot password page$/ new_user_password_path + when /^the two-factor authentication page$/ + two_factor_authentication_path when %r{^"(/.*)"} Regexp.last_match(1) else -- cgit v1.2.3 From 607659939d1113c2840e7b36eced7d6f0c6c637f Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Sun, 28 Apr 2019 18:38:46 +0200 Subject: Enable paranoid mode for devise fixes #8001 closes #8003 --- features/desktop/change_password.feature | 4 ++-- features/mobile/change_password.feature | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'features') diff --git a/features/desktop/change_password.feature b/features/desktop/change_password.feature index 7b30014ec..695193249 100644 --- a/features/desktop/change_password.feature +++ b/features/desktop/change_password.feature @@ -25,7 +25,7 @@ Feature: Change password Given I am on forgot password page When I fill out forgot password form with "forgetful@users.net" And I submit forgot password form - Then I should see "You will receive an email with instructions" + Then I should see "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." When I follow the "Change my password" link from the last sent email When I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form @@ -49,4 +49,4 @@ Feature: Change password Given I am on forgot password page When I fill out forgot password form with "notanemail" And I submit forgot password form - Then I should see "No account with this email exists" + Then I should see "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." diff --git a/features/mobile/change_password.feature b/features/mobile/change_password.feature index f3bcdb445..8f7c0c060 100644 --- a/features/mobile/change_password.feature +++ b/features/mobile/change_password.feature @@ -27,7 +27,7 @@ Feature: Change password And I am on forgot password page When I fill out forgot password form with "forgetful@users.net" And I submit forgot password form - Then I should see "You will receive an email with instructions" + Then I should see "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." When I follow the "Change my password" link from the last sent email And I fill out the password reset form with "supersecret" and "supersecret" And I submit the password reset form @@ -52,4 +52,4 @@ Feature: Change password Given I am on forgot password page When I fill out forgot password form with "notanemail" And I submit forgot password form - Then I should see "No account with this email exists" + Then I should see "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." -- cgit v1.2.3 From 54fd4846c0607ea1a3de07f65e9a39920cf4ba8a Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Tue, 30 Apr 2019 02:36:23 +0200 Subject: Use password to disable 2FA instead of a token Using token doesn't make much sense when you can generate new tokens right below. closes #8006 --- features/desktop/two_factor_authentication.feature | 22 ++++++---------------- features/step_definitions/session_steps.rb | 2 +- features/step_definitions/two_factor_steps.rb | 16 ---------------- 3 files changed, 7 insertions(+), 33 deletions(-) (limited to 'features') diff --git a/features/desktop/two_factor_authentication.feature b/features/desktop/two_factor_authentication.feature index ae8e2d2ef..1e2e8a61f 100644 --- a/features/desktop/two_factor_authentication.feature +++ b/features/desktop/two_factor_authentication.feature @@ -51,40 +51,30 @@ Feature: Two-factor autentication Scenario: Regenerating recovery codes Given a user with email "alice@test.com" - When I sign in as "alice@test.com" And 2fa is activated for "alice@test.com" + When I sign in as "alice@test.com" When I go to the two-factor authentication page Then I should see "Generate new recovery codes" When I press the recovery code generate button Then I should see a list of recovery codes - Scenario: Deactivating 2fa with correct token + Scenario: Deactivating 2fa with correct password Given a user with email "alice@test.com" - When I sign in as "alice@test.com" And 2fa is activated for "alice@test.com" - When I go to the two-factor authentication page - Then I should see "Deactivate" - When I fill in a valid TOTP token to deactivate for "alice@test.com" - And I press "Deactivate" - Then I should see "Two-factor authentication not activated" - - Scenario: Deactivating 2fa with recovery token - Given a user with email "alice@test.com" When I sign in as "alice@test.com" - And 2fa is activated for "alice@test.com" When I go to the two-factor authentication page Then I should see "Deactivate" - When I fill in a recovery code to deactivate from "alice@test.com" + When I put in my password in "two_factor_authentication_password" And I press "Deactivate" Then I should see "Two-factor authentication not activated" - Scenario: Trying to deactivate with incorrect token + Scenario: Trying to deactivate with incorrect password Given a user with email "alice@test.com" - When I sign in as "alice@test.com" And 2fa is activated for "alice@test.com" + When I sign in as "alice@test.com" When I go to the two-factor authentication page Then I should see "Deactivate" - When I fill in an invalid TOTP token to deactivate + When I fill in "two_factor_authentication_password" with "incorrect" And I press "Deactivate" Then I should see "Two-factor authentication activated" And I should see "Deactivate" diff --git a/features/step_definitions/session_steps.rb b/features/step_definitions/session_steps.rb index a31de421f..4b08d1498 100644 --- a/features/step_definitions/session_steps.rb +++ b/features/step_definitions/session_steps.rb @@ -31,7 +31,7 @@ When /^I (?:sign|log) in with password "([^"]*)"( on the mobile website)?$/ do | end When /^I put in my password in "([^"]*)"$/ do |field| - step %(I fill in "#{field}" with "#{@me.password}") + step %(I fill in "#{field}" with "#{@me.password}") end When /^I fill out change password section with my password and "([^"]*)" and "([^"]*)"$/ do |new_pass, confirm_pass| diff --git a/features/step_definitions/two_factor_steps.rb b/features/step_definitions/two_factor_steps.rb index 7b5ab2319..40e3cd7de 100644 --- a/features/step_definitions/two_factor_steps.rb +++ b/features/step_definitions/two_factor_steps.rb @@ -14,15 +14,6 @@ When /^I fill in an invalid TOTP token$/ do fill_in "user_otp_attempt", with: "c0ffee" end -When /^I fill in a valid TOTP token to deactivate for "([^"]*)"$/ do |username| - @me = find_user username - fill_in "two_factor_authentication_code", with: @me.current_otp -end - -When /^I fill in an invalid TOTP token to deactivate$/ do - fill_in "two_factor_authentication_code", with: "c0ffee" -end - When /^I fill in a recovery code from "([^"]*)"$/ do |username| @me = find_user username @codes = @me.generate_otp_backup_codes! @@ -30,13 +21,6 @@ When /^I fill in a recovery code from "([^"]*)"$/ do |username| fill_in "user_otp_attempt", with: @codes.first end -When /^I fill in a recovery code to deactivate from "([^"]*)"$/ do |username| - @me = find_user username - @codes = @me.generate_otp_backup_codes! - @me.save! - fill_in "two_factor_authentication_code", with: @codes.first -end - When /^I confirm activation$/ do find(".btn-primary", match: :first).click end -- cgit v1.2.3 From 554faa41164d67dfc3864b6e4cdda6f55a337e18 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Sun, 28 Apr 2019 13:03:14 +0200 Subject: Reorganize steps a bit --- features/step_definitions/custom_web_steps.rb | 80 +------------------------- features/step_definitions/left_navbar_steps.rb | 23 ++++++++ features/step_definitions/posts_steps.rb | 72 ++--------------------- features/step_definitions/publisher_steps.rb | 74 ++++++++++++++++++++++++ features/step_definitions/stream_steps.rb | 55 +++++++++++++++--- 5 files changed, 152 insertions(+), 152 deletions(-) create mode 100644 features/step_definitions/left_navbar_steps.rb create mode 100644 features/step_definitions/publisher_steps.rb (limited to 'features') diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index 041afe439..15a84578b 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -61,18 +61,6 @@ And /^I submit the form$/ do find("input[type='submit']").click end -And /^I expand the publisher$/ do - click_publisher -end - -And /^I close the publisher$/ do - find("#publisher .md-cancel").click -end - -Then /^the publisher should be expanded$/ do - find("#publisher")["class"].should_not include("closed") -end - Then /^the text area wrapper mobile should be with attachments$/ do find("#publisher-textarea-wrapper")["class"].should include("with_attachments") end @@ -88,48 +76,6 @@ And /^I hover over the "([^"]+)"$/ do |element| find("#{element}", match: :first).hover end -When /^I prepare the deletion of the first post$/ do - find(".stream .stream-element", match: :first).hover - within(find(".stream .stream-element", match: :first)) do - ctrl = find(".control-icons") - ctrl.hover - ctrl.find(".remove_post").click - end -end - -When /^I prepare hiding the first post$/ do - find(".stream .stream-element", match: :first).hover - within(find(".stream .stream-element", match: :first)) do - ctrl = find(".control-icons") - ctrl.hover - ctrl.find(".hide_post").click - end -end - -When /^I click to delete the first post$/ do - accept_alert do - step "I prepare the deletion of the first post" - end - expect(find(".stream")).to have_no_css(".stream-element.loaded.deleting") -end - -When /^I click to hide the first post$/ do - accept_alert do - step "I prepare hiding the first post" - end -end - -When /^I click to delete the first comment$/ do - within("div.comment", match: :first) do - find(".comment_delete", visible: false).click - end -end - -When /^I click to delete the first uploaded photo$/ do - page.execute_script("$('#photodropzone .x').css('display', 'block');") - find("#photodropzone .x", match: :first).trigger "click" -end - And /^I click on selector "([^"]*)"$/ do |selector| find(selector).click end @@ -221,15 +167,7 @@ When /^I resize my window to 800x600$/ do page.driver.resize(800, 600) end -Then 'I should see an image attached to the post' do - step %(I should see a "img" within ".stream-element div.photo-attachments") -end - -Then 'I press the attached image' do - step %(I press the 1st "img" within ".stream-element div.photo-attachments") -end - -And "I wait for the popovers to appear" do +And /^I wait for the popovers to appear$/ do expect(page).to have_selector(".popover", count: 3) end @@ -282,22 +220,6 @@ When /^I focus the "([^"]+)" field$/ do |field| find_field(field).click end -Given /^I have configured a Bitcoin address$/ do - AppConfig.settings.bitcoin_address = "AAAAAA" -end - -Then /^I should see the Bitcoin address$/ do - find("#bitcoin_address")['value'].should == "AAAAAA" -end - -Given /^I have configured a Liberapay username$/ do - AppConfig.settings.liberapay_username = "BBBBBB" -end - -Then /^I should see the Liberapay donate button$/ do - find("#liberapay-button")["href"].should == "https://liberapay.com/BBBBBB/donate" -end - Given /^"([^"]*)" is hidden$/ do |selector| page.should have_selector(selector, visible: false) page.should_not have_selector(selector) diff --git a/features/step_definitions/left_navbar_steps.rb b/features/step_definitions/left_navbar_steps.rb new file mode 100644 index 000000000..4a88bebb1 --- /dev/null +++ b/features/step_definitions/left_navbar_steps.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +When /^(?:|I )click on "([^"]*)" navbar title$/ do |title| + with_scope(".info-bar") do + find("h5", text: title).click + end +end + +Given /^I have configured a Bitcoin address$/ do + AppConfig.settings.bitcoin_address = "AAAAAA" +end + +Then /^I should see the Bitcoin address$/ do + find("#bitcoin_address")['value'].should == "AAAAAA" +end + +Given /^I have configured a Liberapay username$/ do + AppConfig.settings.liberapay_username = "BBBBBB" +end + +Then /^I should see the Liberapay donate button$/ do + find("#liberapay-button")["href"].should == "https://liberapay.com/BBBBBB/donate" +end diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb index 7f8c93466..da3ee2924 100644 --- a/features/step_definitions/posts_steps.rb +++ b/features/step_definitions/posts_steps.rb @@ -8,36 +8,6 @@ Then /^the post should be expanded$/ do first_post_expanded? end -Then /^I should see an uploaded image within the photo drop zone$/ do - expect(find("#photodropzone img")["src"]).to include("uploads/images") -end - -Then /^I should not see an uploaded image within the photo drop zone$/ do - page.should_not have_css "#photodropzone img" -end - -Then /^I should not see any posts in my stream$/ do - expect(page).not_to have_selector("#paginate .loader") - expect(page).not_to have_selector(".stream-element .media") - expect(page).to have_selector(".stream-element .no-posts-info") -end - -Then /^I should not see any picture in my stream$/ do - expect(page).to have_selector(".photo_area img", count: 0) -end - -Then /^I should see (\d+) pictures in my stream$/ do |count| - expect(page).to have_selector(".photo_area img", count: count) -end - -Then /^I should not be able to submit the publisher$/ do - expect(publisher_submittable?).to be false -end - -Then /^I should see "([^"]*)" in the publisher$/ do |text| - expect(page).to have_field("status_message[text]", with: text) -end - Given /^I have a limited post with text "([^\"]*)" in the aspect "([^"]*)"$/ do |text, aspect_name| @me.post :status_message, text: text, to: @me.aspects.where(name: aspect_name).first.id end @@ -83,10 +53,6 @@ And /^the post with text "([^"]*)" is reshared by "([^"]*)"$/ do |text, email| user.post(:reshare, :root_guid => root.guid, :public => true, :to => user.aspect_ids) end -And /^I submit the publisher$/ do - submit_publisher -end - When /^I click on the first block button/ do find(".stream-element", match: :first).hover find(".block_user").click @@ -100,40 +66,14 @@ When /^I expand the post$/ do expand_first_post end -When /^I click the publisher and post "([^"]*)"$/ do |text| - click_and_post(text) -end - -When /^I post an extremely long status message$/ do - click_and_post("I am a very interesting message " * 64) -end - -When /^I write the status message "([^"]*)"$/ do |text| - write_in_publisher(text) -end - -When /^I insert an extremely long status message$/ do - write_in_publisher("I am a very interesting message " * 64) -end - -When /^I append "([^"]*)" to the publisher$/ do |text| - append_to_publisher(text) -end - -When /^I attach "([^"]*)" to the publisher$/ do |path| - upload_file_with_publisher(path) -end - When /^I open the show page of the "([^"]*)" post$/ do |post_text| visit post_path_by_content(post_text) end -When /^I select "([^"]*)" on the aspect dropdown$/ do |text| - page.execute_script( - "$('#publisher .dropdown .dropdown_list, #publisher .aspect-dropdown .dropdown-menu') - .find('li').each(function(i,el){ - var elem = $(el); - if ('" + text + "' == $.trim(elem.text()) ) { - elem.click(); - }});") +Then /^I should see an image attached to the post$/ do + step %(I should see a "img" within ".stream-element div.photo-attachments") +end + +Then /^I press the attached image$/ do + step %(I press the 1st "img" within ".stream-element div.photo-attachments") end diff --git a/features/step_definitions/publisher_steps.rb b/features/step_definitions/publisher_steps.rb new file mode 100644 index 000000000..8479b1429 --- /dev/null +++ b/features/step_definitions/publisher_steps.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +Then /^I expand the publisher$/ do + click_publisher +end + +And /^I close the publisher$/ do + find("#publisher .md-cancel").click +end + +Then /^the publisher should be expanded$/ do + find("#publisher")["class"].should_not include("closed") +end + +When /^I click to delete the first uploaded photo$/ do + page.execute_script("$('#photodropzone .x').css('display', 'block');") + image_count = all(".publisher_photo img", wait: false).count + find("#photodropzone .x", match: :first).trigger "click" + page.assert_selector(".publisher_photo img", count: image_count - 1) +end + +Then /^I should see an uploaded image within the photo drop zone$/ do + expect(find("#photodropzone img")["src"]).to include("uploads/images") +end + +Then /^I should not see an uploaded image within the photo drop zone$/ do + page.should_not have_css "#photodropzone img" +end + +Then /^I should not be able to submit the publisher$/ do + expect(publisher_submittable?).to be false +end + +Then /^I should see "([^"]*)" in the publisher$/ do |text| + expect(page).to have_field("status_message[text]", with: text) +end + +When /^I write the status message "([^"]*)"$/ do |text| + write_in_publisher(text) +end + +When /^I insert an extremely long status message$/ do + write_in_publisher("I am a very interesting message " * 64) +end + +When /^I append "([^"]*)" to the publisher$/ do |text| + append_to_publisher(text) +end + +When /^I attach "([^"]*)" to the publisher$/ do |path| + upload_file_with_publisher(path) +end + +And /^I submit the publisher$/ do + submit_publisher +end + +When /^I click the publisher and post "([^"]*)"$/ do |text| + click_and_post(text) +end + +When /^I post an extremely long status message$/ do + click_and_post("I am a very interesting message " * 64) +end + +When /^I select "([^"]*)" on the aspect dropdown$/ do |text| + page.execute_script( + "$('#publisher .dropdown .dropdown_list, #publisher .aspect-dropdown .dropdown-menu') + .find('li').each(function(i,el){ + var elem = $(el); + if ('" + text + "' == $.trim(elem.text()) ) { + elem.click(); + }});") +end diff --git a/features/step_definitions/stream_steps.rb b/features/step_definitions/stream_steps.rb index 5d241eaa0..eacc1668e 100644 --- a/features/step_definitions/stream_steps.rb +++ b/features/step_definitions/stream_steps.rb @@ -4,10 +4,6 @@ When /^I (?:like|unlike) the post "([^"]*)" in the stream$/ do |post_text| like_stream_post(post_text) end -Then /^I should see an image in the publisher$/ do - photo_in_publisher.should be_present -end - Then /^"([^"]*)" should be post (\d+)$/ do |post_text, position| stream_element_numbers_content(position).should have_content(post_text) end @@ -24,8 +20,53 @@ Then /^I should have (\d+) nsfw posts$/ do |num_posts| page.should have_css(".nsfw-shield", count: num_posts.to_i) end -When /^(?:|I )click on "([^"]*)" navbar title$/ do |title| - with_scope(".info-bar") do - find("h5", text: title).click +When /^I prepare the deletion of the first post$/ do + find(".stream .stream-element", match: :first).hover + within(find(".stream .stream-element", match: :first)) do + ctrl = find(".control-icons") + ctrl.hover + ctrl.find(".remove_post").click + end +end + +When /^I prepare hiding the first post$/ do + find(".stream .stream-element", match: :first).hover + within(find(".stream .stream-element", match: :first)) do + ctrl = find(".control-icons") + ctrl.hover + ctrl.find(".hide_post").click + end +end + +When /^I click to delete the first post$/ do + accept_alert do + step "I prepare the deletion of the first post" + end + expect(find(".stream")).to have_no_css(".stream-element.loaded.deleting") +end + +When /^I click to hide the first post$/ do + accept_alert do + step "I prepare hiding the first post" end end + +When /^I click to delete the first comment$/ do + within("div.comment", match: :first) do + find(".comment_delete", visible: false).click + end +end + +Then /^I should not see any posts in my stream$/ do + expect(page).not_to have_selector("#paginate .loader") + expect(page).not_to have_selector(".stream-element .media") + expect(page).to have_selector(".stream-element .no-posts-info") +end + +Then /^I should not see any picture in my stream$/ do + expect(page).to have_selector(".photo_area img", count: 0) +end + +Then /^I should see (\d+) pictures in my stream$/ do |count| + expect(page).to have_selector(".photo_area img", count: count) +end -- cgit v1.2.3 From 83a9877def158b282a9afe0d424bc81329e2b1c5 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Sun, 28 Apr 2019 15:02:28 +0200 Subject: Improve likes steps closes #8002 --- features/desktop/likes.feature | 13 +++++++----- features/step_definitions/left_navbar_steps.rb | 2 +- features/step_definitions/publisher_steps.rb | 3 ++- features/step_definitions/stream_steps.rb | 29 ++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) (limited to 'features') diff --git a/features/desktop/likes.feature b/features/desktop/likes.feature index 73227004d..02bd395e8 100644 --- a/features/desktop/likes.feature +++ b/features/desktop/likes.feature @@ -16,13 +16,14 @@ Feature: Liking posts Scenario: Liking and unliking a post from the stream Then I should not have activated notifications for the post When I like the post "I like unicorns" in the stream - Then I should see "Unlike" within ".stream-element .feedback" - And I should see a ".likes .media" within "#main-stream .stream-element" + Then the post "I like unicorns" should have the "Unlike" action available + And the post "I like unicorns" should have 1 like + And the post "I like unicorns" should have a like from "Alice Smith" And I should have activated notifications for the post When I unlike the post "I like unicorns" in the stream - Then I should see "Like" within ".stream-element .feedback" - And I should not see a ".likes .media" within "#main-stream .stream-element" + Then the post "I like unicorns" should have the "Like" action available + And the post "I like unicorns" shouldn't have any likes Scenario: Liking and unliking a post from a single post page @@ -39,4 +40,6 @@ Feature: Liking posts When I like the post "I like unicorns" in the stream And I sign out And I sign in as "bob@bob.bob" - Then I should see a ".likes" within "#main-stream .stream-element" + Then the post "I like unicorns" should have the "Like" action available + And the post "I like unicorns" should have 1 like + And the post "I like unicorns" should have a like from "Alice Smith" diff --git a/features/step_definitions/left_navbar_steps.rb b/features/step_definitions/left_navbar_steps.rb index 4a88bebb1..f84f3526a 100644 --- a/features/step_definitions/left_navbar_steps.rb +++ b/features/step_definitions/left_navbar_steps.rb @@ -11,7 +11,7 @@ Given /^I have configured a Bitcoin address$/ do end Then /^I should see the Bitcoin address$/ do - find("#bitcoin_address")['value'].should == "AAAAAA" + find("#bitcoin_address")["value"].should == "AAAAAA" end Given /^I have configured a Liberapay username$/ do diff --git a/features/step_definitions/publisher_steps.rb b/features/step_definitions/publisher_steps.rb index 8479b1429..f0d6a8c46 100644 --- a/features/step_definitions/publisher_steps.rb +++ b/features/step_definitions/publisher_steps.rb @@ -70,5 +70,6 @@ When /^I select "([^"]*)" on the aspect dropdown$/ do |text| var elem = $(el); if ('" + text + "' == $.trim(elem.text()) ) { elem.click(); - }});") + }});" + ) end diff --git a/features/step_definitions/stream_steps.rb b/features/step_definitions/stream_steps.rb index eacc1668e..853df81ca 100644 --- a/features/step_definitions/stream_steps.rb +++ b/features/step_definitions/stream_steps.rb @@ -4,6 +4,35 @@ When /^I (?:like|unlike) the post "([^"]*)" in the stream$/ do |post_text| like_stream_post(post_text) end +Then /^the post "([^"]*)" should have the "([^"]*)" action available$/ do |post_text, action_text| + within_post(post_text) do + find(".feedback").should have_content(action_text) + end +end + +Then /^the post "([^"]*)" shouldn't have any likes$/ do |post_text| + within_post(post_text) do + find(".likes").should have_no_css(".avatar", visible: true) + end +end + +Then /^the post "([^"]*)" should have (\d+) like(?:s|)$/ do |post_text, likes_number| + within_post(post_text) do + find(".expand-likes").should have_content(likes_number) + end +end + +Then /^the post "([^"]*)" should have a like from "([^"]*)"$/ do |post_text, username| + within_post(post_text) do + find(".expand-likes").click + find(".likes .avatar")["data-original-title"].should have_content(username) + end +end + +Then /^I should see an image in the publisher$/ do + photo_in_publisher.should be_present +end + Then /^"([^"]*)" should be post (\d+)$/ do |post_text, position| stream_element_numbers_content(position).should have_content(post_text) end -- cgit v1.2.3 From 4feab5219e7c9943a98512001e9080dc2937bbc3 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Thu, 2 May 2019 17:27:27 +0200 Subject: Use a partial to share code between mobile and desktop, add the new route to the RegistrationController, drop flash message for closed registrations --- features/desktop/getting_started.feature | 108 +++++++++++++++++++++++++++++ features/desktop/registrations.feature | 24 +++++++ features/desktop/signs_up.feature | 108 ----------------------------- features/mobile/registrations.feature | 35 ++++++++++ features/mobile/signs_up.feature | 36 ---------- features/step_definitions/session_steps.rb | 8 +++ features/step_definitions/user_steps.rb | 8 --- 7 files changed, 175 insertions(+), 152 deletions(-) create mode 100644 features/desktop/getting_started.feature create mode 100644 features/desktop/registrations.feature delete mode 100644 features/desktop/signs_up.feature create mode 100644 features/mobile/registrations.feature delete mode 100644 features/mobile/signs_up.feature (limited to 'features') diff --git a/features/desktop/getting_started.feature b/features/desktop/getting_started.feature new file mode 100644 index 000000000..bbebd5efa --- /dev/null +++ b/features/desktop/getting_started.feature @@ -0,0 +1,108 @@ +@javascript +Feature: new user registration + + Background: + When I go to the new user registration page + And I fill in the new user form + And I submit the form + Then I should be on the getting started page + Then I should see the 'getting started' contents + + Scenario: new user goes through the setup wizard + When I fill in the following: + | profile_first_name | O | + And I confirm the alert after I follow "awesome_button" + Then I should be on the stream page + And the publisher should be expanded + And I close the publisher + Then I should not see "awesome_button" + And I should not see any posts in my stream + + Scenario: new user tries to XSS itself + When I fill in the following: + | profile_first_name |