diff --git a/app/views/groups/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb b/app/views/groups/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb index e983d6c7b4..0e93daf8c5 100644 --- a/app/views/groups/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb +++ b/app/views/groups/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb @@ -1,4 +1,4 @@ -<%= viral_dialog(open: open, size: :extra_large) do |dialog| %> +<%= viral_dialog(open: open, id: 'bot_tokens_dialog', size: :extra_large) do |dialog| %> <%= dialog.with_header( title: t("groups.bots.index.personal_access_tokens_listing_modal.title"), ) %> diff --git a/app/views/groups/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb b/app/views/groups/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb index 3ecffe37f7..491e75e0a6 100644 --- a/app/views/groups/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb +++ b/app/views/groups/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb @@ -1,4 +1,4 @@ -<%= viral_dialog(open: open) do |dialog| %> +<%= viral_dialog(open: open, id: 'revoke_confirmation_dialog') do |dialog| %> <%= dialog.with_header(title: t("personal_access_tokens.revoke_confirmation.title")) %> <%= dialog.with_section do %> diff --git a/app/views/projects/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb b/app/views/projects/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb index de940a871a..1581532df3 100644 --- a/app/views/projects/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb +++ b/app/views/projects/bots/personal_access_tokens/_personal_access_token_listing_modal.html.erb @@ -1,4 +1,4 @@ -<%= viral_dialog(open: open, size: :extra_large) do |dialog| %> +<%= viral_dialog(open: open, id: 'bot_tokens_dialog', size: :extra_large) do |dialog| %> <%= dialog.with_header( title: t("projects.bots.index.personal_access_tokens_listing_modal.title"), ) %> diff --git a/app/views/projects/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb b/app/views/projects/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb index 46c39b5fbe..46db36bfb8 100644 --- a/app/views/projects/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb +++ b/app/views/projects/bots/personal_access_tokens/_revoke_confirmation_modal.html.erb @@ -1,4 +1,4 @@ -<%= viral_dialog(open: open) do |dialog| %> +<%= viral_dialog(open: open, id: 'revoke_confirmation_dialog') do |dialog| %> <%= dialog.with_header(title: t("personal_access_tokens.revoke_confirmation.title")) %> <%= dialog.with_section do %> diff --git a/test/system/groups/bots_test.rb b/test/system/groups/bots_test.rb index 279f24b09d..4cdf56fc58 100644 --- a/test/system/groups/bots_test.rb +++ b/test/system/groups/bots_test.rb @@ -4,10 +4,12 @@ module Groups class BotsTest < ApplicationSystemTestCase + include ActionView::Helpers::SanitizeHelper header_row_count = 1 def setup - login_as users(:john_doe) + @user = users(:john_doe) + login_as @user @namespace = groups(:group_one) @group_bot = namespace_bots(:group1_bot0) @group_bot_active_tokens = @group_bot.user.personal_access_tokens.active @@ -16,20 +18,26 @@ def setup test 'can see a table listing of group bot accounts' do visit group_bots_path(@namespace) + # header and description assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.subtitle') + # table assert_selector 'tr', count: 20 + header_row_count + # pagy assert_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ assert_no_selector 'a', text: I18n.t(:'components.pagination.previous') + # second page of table click_on I18n.t(:'components.pagination.next') assert_selector 'tr', count: 1 + header_row_count + # pagy updated assert_selector 'a', text: I18n.t(:'components.pagination.previous') assert_no_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ + # pagy previous works click_on I18n.t(:'components.pagination.previous') assert_selector 'tr', count: 20 + header_row_count end @@ -52,6 +60,7 @@ def setup end test 'can create a new group bot account' do + ### VERIFY START ### namespace = groups(:group_two) visit group_bots_path(namespace) @@ -66,10 +75,13 @@ def setup assert_text I18n.t(:'bots.index.table.empty_state.title') assert_text I18n.t(:'bots.index.table.empty_state.description') end + ### SETUP END ### + ### ACTIONS START ### click_link I18n.t(:'groups.bots.index.add_new_bot') - within('dialog') do + assert_selector '#dialog' + within('#dialog') do assert_selector 'h1', text: I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.description') @@ -81,9 +93,12 @@ def setup click_button I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.submit') end + ### ACTIONS END ### - assert_no_selector 'dialog[open]' + ### VERIFY START ### + assert_no_selector '#dialog' + assert_selector '#access-token-section div' within('#access-token-section') do bot_account_name = namespace.bots.last.email @@ -93,9 +108,11 @@ def setup end assert_selector 'tr', count: 1 + header_row_count + ### VERIFY END ### end test 'can\'t create a new group bot account without selecting scopes' do + ### SETUP START ### visit group_bots_path(groups(:group_two)) assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') @@ -109,10 +126,13 @@ def setup assert_text I18n.t(:'bots.index.table.empty_state.title') assert_text I18n.t(:'bots.index.table.empty_state.description') end + ### SETUP END ### + ### ACTIONS START ### click_link I18n.t(:'groups.bots.index.add_new_bot') - within('dialog') do + assert_selector '#dialog' + within('#dialog') do assert_selector 'h1', text: I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.description') @@ -123,44 +143,68 @@ def setup assert_html5_inputs_valid click_button I18n.t(:'groups.bots.index.bot_listing.new_bot_modal.submit') + ### ACTIONS END ### + ### VERIFY START ### + assert_selector '#new_bot_account-error-alert' within('#new_bot_account-error-alert') do assert_text I18n.t(:'services.bots.create.required.scopes') end end + ### VERIFY END ### end test 'can delete a group bot account' do + ### SETUP START ### visit group_bots_path(@namespace) assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### - within('table') do - within('table tbody tr:first-child td:last-child') do - click_link I18n.t(:'bots.index.table.actions.destroy') - end + ### ACTIONS START ### + within('table tbody tr:first-child td:last-child') do + click_link I18n.t(:'bots.index.table.actions.destroy') end - - within('dialog') do + assert_selector '#dialog' + within('#dialog') do click_button I18n.t('bots.destroy_confirmation.submit_button') end - assert_text I18n.t(:'concerns.bot_actions.destroy.success') + ### ACTIONS END ### + ### VERIFY START ### + # success message + assert_text I18n.t(:'concerns.bot_actions.destroy.success') + # bot number decreased by 1 + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 20, + locale: @user.locale)) + # no pagy next/previous buttons since only 1 page for table assert_no_selector 'a', text: I18n.t(:'components.pagination.previous') assert_no_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ + ### VERIFY END ### end test 'can view personal access tokens for bot account' do + ### SETUP START ### + token = @group_bot_active_tokens.first visit group_bots_path(@namespace) assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### + ### ACTIONS START ### within "tr[id='#{@group_bot.id}']" do click_link @group_bot_active_tokens.count.to_s end + ### ACTIONS END ### - within('dialog') do + ### VERIFY START ### + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do assert_selector 'h1', text: I18n.t('groups.bots.index.personal_access_tokens_listing_modal.title') assert_selector 'p', text: I18n.t( @@ -190,98 +234,128 @@ def setup end end end + ### VERIFY END ### end test 'can generate a new personal access token for bot account' do + ### SETUP START ### + initial_token_count = @group_bot_active_tokens.count visit group_bots_path(@namespace) + # verify page and table loaded assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### + ### ACTIONS START ### within "tr[id='#{@group_bot.id}']" do - click_link 'Generate new token' + click_link I18n.t('bots.index.table.actions.generate_new_token') end - within('dialog') do - assert_text I18n.t( - 'groups.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) - + # verify dialog rendered + assert_selector '#dialog' + within('#dialog') do + assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @group_bot.user.email) - fill_in I18n.t('groups.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.submit') end + ### ACTIONS END ### + ### VERIFY START ### + assert_selector '#access-token-section div' within('#access-token-section') do assert_selector 'h2', text: I18n.t('groups.bots.index.access_token_section.label', bot_name: @group_bot.user.email) assert_selector 'p', text: I18n.t('groups.bots.index.access_token_section.description') assert_selector 'button', text: I18n.t('components.token.copy') end + # verify token count increased + within "tr[id='#{@group_bot.id}'] td:nth-child(2)" do + assert_text (initial_token_count + 1).to_s + end + ### VERIFY END ### end test 'can revoke a personal access token' do + ### SETUP START ### token = @group_bot_active_tokens.first + initial_token_count = @group_bot_active_tokens.count visit group_bots_path(@namespace) + # verify page rendered assert_selector 'h1', text: I18n.t(:'groups.bots.index.title') assert_selector 'p', text: I18n.t(:'groups.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### + ### ACTIONS START ### within "tr[id='#{@group_bot.id}']" do - click_link @group_bot_active_tokens.count.to_s + assert_text initial_token_count.to_s + # open bot PAT dialog + click_link initial_token_count.to_s end - within('dialog') do - assert_selector 'h1', text: I18n.t('groups.bots.index.personal_access_tokens_listing_modal.title') - assert_selector 'p', - text: I18n.t( - 'groups.bots.index.personal_access_tokens_listing_modal.description', - bot_account: @group_bot.user.email - ) - - within('table') do - assert_selector 'tr', count: 2 - - within "tr[id='#{token.id}']" do - click_link I18n.t('personal_access_tokens.table.revoke') - end + # verify bots token dialog rendered + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do + # verify PAT table rendered + assert_selector '#personal_access_tokens' + within('table tbody') do + assert_selector 'tr', count: 1 + end + # revoke PAT + within "tr[id='#{token.id}']" do + click_link I18n.t('personal_access_tokens.table.revoke') end end - within('dialog') do + # verify revoke dialog rendered + assert_selector '#revoke_confirmation_dialog' + within('#revoke_confirmation_dialog') do + assert_text I18n.t('personal_access_tokens.revoke_confirmation.title') + # revoke click_button I18n.t('personal_access_tokens.revoke_confirmation.submit_button') - within('#personal-access-token-alert') do - assert_text I18n.t('concerns.bot_personal_access_token_actions.revoke.success', pat_name: token.name) - end end + ### ACTIONS END ### + + ### VERIFY START ### + # success msg + assert_selector '#personal-access-token-alert' + within('#personal-access-token-alert') do + assert_text I18n.t('concerns.bot_personal_access_token_actions.revoke.success', pat_name: token.name) + end + + # verify token count decreased + within "tr[id='#{@group_bot.id}'] td:nth-child(2)" do + assert_text (initial_token_count - 1).to_s + end + ### VERIFY END ### end test 'PAT panel removed after personal access token revoke' do ### SETUP START ### - visit group_bots_path(@namespace) - # PAT panel is not present + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + # PAT turbo frame present with no content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' # create new PAT to render PAT panel within "tr[id='#{@group_bot.id}']" do click_link I18n.t('bots.index.table.actions.generate_new_token') end + assert_selector '#dialog' within('#dialog') do - assert_text I18n.t( - 'groups.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) - + assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @group_bot.user.email) - fill_in I18n.t('groups.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.submit') end @@ -304,18 +378,28 @@ def setup end # bot's current PATs dialog - within('#dialog') do + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do + assert_selector '#personal_access_tokens' + within('table tbody') do + assert_selector 'tr', count: 2 + end # revoke a PAT within("table tbody tr[id='#{@group_bot_active_tokens.first.id}']") do click_link I18n.t('personal_access_tokens.table.revoke') end + end + assert_selector '#revoke_confirmation_dialog' + within('#revoke_confirmation_dialog') do + assert_text I18n.t('personal_access_tokens.revoke_confirmation.title') click_button I18n.t('personal_access_tokens.revoke_confirmation.submit_button') end ### ACTIONS END ### ### VERIFY START ### - # PAT panel no longer present + # PAT panel no longer contains content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' ### VERIFY END ### end @@ -323,25 +407,24 @@ def setup test 'PAT panel removed after bot destroy' do ### SETUP START ### visit group_bots_path(@namespace) - # PAT panel is not present + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + # PAT turbo frame present with no content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' # create new PAT to render PAT panel within "tr[id='#{@group_bot.id}']" do click_link I18n.t('bots.index.table.actions.generate_new_token') end + assert_selector '#dialog' within('#dialog') do - assert_text I18n.t( - 'groups.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) - + assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @group_bot.user.email) - + # fill in PAT values fill_in I18n.t('groups.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('groups.bots.index.bot_listing.generate_personal_access_token_modal.submit') end @@ -364,11 +447,18 @@ def setup end # confirm destroy bot - click_button I18n.t('bots.destroy_confirmation.submit_button') + within('#dialog') do + assert_text I18n.t('bots.destroy_confirmation.description', bot_name: @group_bot.user.email) + click_button I18n.t('bots.destroy_confirmation.submit_button') + end ### ACTIONS END ### ### VERIFY START ### - # PAT panel no longer present + # confirm bot destroyed + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 20, + locale: @user.locale)) + # PAT panel no longer contains content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' ### VERIFY END ### end diff --git a/test/system/projects/bots_test.rb b/test/system/projects/bots_test.rb index d5063a32c1..73940f04ea 100644 --- a/test/system/projects/bots_test.rb +++ b/test/system/projects/bots_test.rb @@ -4,10 +4,12 @@ module Projects class BotsTest < ApplicationSystemTestCase + include ActionView::Helpers::SanitizeHelper header_row_count = 1 def setup - login_as users(:john_doe) + @user = users(:john_doe) + login_as @user @namespace = groups(:group_one) @project = projects(:project1) @project2 = projects(:project2) @@ -18,20 +20,26 @@ def setup test 'can see a table listing of project bot accounts' do visit namespace_project_bots_path(@namespace, @project) + # header and description assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.subtitle') + # table assert_selector 'tr', count: 20 + header_row_count + # pagy assert_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ assert_no_selector 'a', text: I18n.t(:'components.pagination.previous') + # second page of table click_on I18n.t(:'components.pagination.next') assert_selector 'tr', count: 1 + header_row_count + # pagy updated assert_selector 'a', text: I18n.t(:'components.pagination.previous') assert_no_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ + # pagy previous works click_on I18n.t(:'components.pagination.previous') assert_selector 'tr', count: 20 + header_row_count end @@ -54,6 +62,7 @@ def setup end test 'can create a new project bot account' do + ### VERIFY START ### visit namespace_project_bots_path(@namespace, @project2) assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') @@ -67,10 +76,13 @@ def setup assert_text I18n.t(:'bots.index.table.empty_state.title') assert_text I18n.t(:'bots.index.table.empty_state.description') end + ### SETUP END ### + ### ACTIONS START ### click_link I18n.t(:'projects.bots.index.add_new_bot') - within('dialog') do + assert_selector '#dialog' + within('#dialog') do assert_selector 'h1', text: I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.description') @@ -82,9 +94,12 @@ def setup click_button I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.submit') end + ### ACTIONS END ### - assert_no_selector 'dialog[open]' + ### VERIFY START ### + assert_no_selector '#dialog' + assert_selector '#access-token-section div' within('#access-token-section') do bot_account_name = @project2.namespace.bots.last.email assert_selector 'h2', text: I18n.t('projects.bots.index.access_token_section.label', bot_name: bot_account_name) @@ -93,9 +108,11 @@ def setup end assert_selector 'tr', count: 1 + header_row_count + ### VERIFY END ### end test 'can\'t create a new project bot account without selecting scopes' do + ### SETUP START ### visit namespace_project_bots_path(@namespace, @project2) assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') @@ -109,10 +126,13 @@ def setup assert_text I18n.t(:'bots.index.table.empty_state.title') assert_text I18n.t(:'bots.index.table.empty_state.description') end + ### SETUP END ### + ### ACTIONS START ### click_link I18n.t(:'projects.bots.index.add_new_bot') - within('dialog') do + assert_selector '#dialog' + within('#dialog') do assert_selector 'h1', text: I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.description') @@ -123,46 +143,69 @@ def setup assert_html5_inputs_valid click_button I18n.t(:'projects.bots.index.bot_listing.new_bot_modal.submit') + ### ACTIONS END ### + ### VERIFY START ### + assert_selector '#new_bot_account-error-alert' within('#new_bot_account-error-alert') do assert_text I18n.t(:'services.bots.create.required.scopes') end end + ### VERIFY END ### end test 'can delete a project bot account' do + ### SETUP START ### visit namespace_project_bots_path(@namespace, @project) assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### - within('table') do - within('table tbody tr:first-child td:last-child') do - click_link I18n.t(:'bots.index.table.actions.destroy') - end + ### ACTIONS START ### + within('table tbody tr:first-child td:last-child') do + click_link I18n.t(:'bots.index.table.actions.destroy') end - within('dialog') do + assert_selector '#dialog' + within('#dialog') do click_button I18n.t('bots.destroy_confirmation.submit_button') end + ### ACTIONS END ### + ### VERIFY START ### + # success message assert_text I18n.t(:'concerns.bot_actions.destroy.success') - + # bot number decreased by 1 + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 20, + locale: @user.locale)) + # no pagy next/previous buttons since only 1 page for table assert_no_selector 'a', text: I18n.t(:'components.pagination.previous') assert_no_selector 'a', text: /\A#{I18n.t(:'components.pagination.next')}\Z/ + ### VERIFY END ### end test 'can view personal access tokens for bot account' do + ### SETUP START ### token = @project_bot_active_tokens.first visit namespace_project_bots_path(@namespace, @project) assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### + ### ACTIONS START ### within "tr[id='#{@project_bot.id}']" do click_link @project_bot_active_tokens.count.to_s end + ### ACTIONS END ### - within('dialog') do + ### VERIFY START ### + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do assert_selector 'h1', text: I18n.t('projects.bots.index.personal_access_tokens_listing_modal.title') assert_selector 'p', text: I18n.t( @@ -191,95 +234,132 @@ def setup end end end + ### VERIFY END ### end test 'can generate a new personal access token for bot account' do + ### SETUP START ### + initial_token_count = @project_bot_active_tokens.count visit namespace_project_bots_path(@namespace, @project) + # verify page and table loaded assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### + ### ACTIONS START ### within "tr[id='#{@project_bot.id}']" do - click_link 'Generate new token' + click_link I18n.t('bots.index.table.actions.generate_new_token') end - within('dialog') do - assert_text I18n.t( - 'projects.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) + # verify dialog rendered + assert_selector '#dialog' + within('#dialog') do + assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @project_bot.user.email) - + # fill token params fill_in I18n.t('projects.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.submit') end + ### ACTIONS END ### + ### VERIFY START ### + assert_selector '#access-token-section div' within('#access-token-section') do - bot_account_name = @project_bot.user.email - assert_selector 'h2', text: I18n.t('projects.bots.index.access_token_section.label', bot_name: bot_account_name) + assert_selector 'h2', text: I18n.t('projects.bots.index.access_token_section.label', + bot_name: @project_bot.user.email) assert_selector 'p', text: I18n.t('projects.bots.index.access_token_section.description') assert_selector 'button', text: I18n.t('components.token.copy') end + # verify token count increased + within "tr[id='#{@project_bot.id}'] td:nth-child(2)" do + assert_text (initial_token_count + 1).to_s + end + ### VERIFY END ### end test 'can revoke a personal access token' do + ### SETUP START ### token = @project_bot_active_tokens.first + initial_token_count = @project_bot_active_tokens.count visit namespace_project_bots_path(@namespace, @project) - + # verify page rendered assert_selector 'h1', text: I18n.t(:'projects.bots.index.title') assert_selector 'p', text: I18n.t(:'projects.bots.index.subtitle') + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + ### SETUP END ### - within "tr[id='#{@project_bot.id}']" do - click_link @project_bot_active_tokens.count.to_s + ### ACTIONS START ### + within "tr[id='#{@project_bot.id}'] td:nth-child(2)" do + assert_text initial_token_count.to_s + # open bot PAT dialog + click_link initial_token_count.to_s end - within('dialog') do - assert_selector 'h1', text: I18n.t('projects.bots.index.personal_access_tokens_listing_modal.title') - assert_selector 'p', - text: I18n.t( - 'projects.bots.index.personal_access_tokens_listing_modal.description', - bot_account: @project_bot.user.email - ) - - within('table') do - assert_selector 'tr', count: 2 - within "tr[id='#{token.id}']" do - click_link 'Revoke' - end + # verify bots token dialog rendered + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do + # verify PAT table rendered + assert_selector '#personal_access_tokens' + within('table tbody') do + assert_selector 'tr', count: 1 end + # revoke PAT + within("table tbody tr[id='#{token.id}']") do + click_link I18n.t('personal_access_tokens.table.revoke') + end + end + + # verify revoke dialog rendered + assert_selector '#revoke_confirmation_dialog' + within('#revoke_confirmation_dialog') do + assert_text I18n.t('personal_access_tokens.revoke_confirmation.title') + # revoke + click_button I18n.t('personal_access_tokens.revoke_confirmation.submit_button') end + ### ACTIONS END ### - click_button I18n.t('personal_access_tokens.revoke_confirmation.submit_button') + ### VERIFY START ### + # success msg + assert_selector '#personal-access-token-alert' within('#personal-access-token-alert') do assert_text I18n.t('concerns.bot_personal_access_token_actions.revoke.success', pat_name: token.name) end + + # verify token count decreased + within "tr[id='#{@project_bot.id}'] td:nth-child(2)" do + assert_text (initial_token_count - 1).to_s + end + ### VERIFY END ### end test 'PAT panel removed after personal access token revoke' do ### SETUP START ### visit namespace_project_bots_path(@namespace, @project) - # PAT panel is not present + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + # PAT turbo frame present with no content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' # create new PAT to render PAT panel within "tr[id='#{@project_bot.id}']" do click_link I18n.t('bots.index.table.actions.generate_new_token') end + # verify dialog rendered + assert_selector '#dialog' within('#dialog') do - assert_text I18n.t( - 'projects.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) - + assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @project_bot.user.email) fill_in I18n.t('projects.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.submit') end @@ -302,18 +382,28 @@ def setup end # bot's current PATs dialog - within('#dialog') do + assert_selector '#bot_tokens_dialog' + within('#bot_tokens_dialog') do + assert_selector '#personal_access_tokens' + within('table tbody') do + assert_selector 'tr', count: 2 + end # revoke a PAT within("table tbody tr[id='#{@project_bot_active_tokens.first.id}']") do click_link I18n.t('personal_access_tokens.table.revoke') end + end + assert_selector '#revoke_confirmation_dialog' + within('#revoke_confirmation_dialog') do + assert_text I18n.t('personal_access_tokens.revoke_confirmation.title') click_button I18n.t('personal_access_tokens.revoke_confirmation.submit_button') end ### ACTIONS END ### ### VERIFY START ### - # PAT panel no longer present + # PAT panel no longer contains content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' ### VERIFY END ### end @@ -321,25 +411,25 @@ def setup test 'PAT panel removed after bot destroy' do ### SETUP START ### visit namespace_project_bots_path(@namespace, @project) - # PAT panel is not present + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 21, + locale: @user.locale)) + # PAT turbo frame present with no content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' # create new PAT to render PAT panel within "tr[id='#{@project_bot.id}']" do click_link I18n.t('bots.index.table.actions.generate_new_token') end + # verify dialog rendered + assert_selector '#dialog' within('#dialog') do - assert_text I18n.t( - 'projects.bots.index.bot_listing.generate_personal_access_token_modal.title' - ) - + assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.title') assert_text I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.description', bot_account: @project_bot.user.email) - + # fill in PAT values fill_in I18n.t('projects.bots.index.bot_listing.new_bot_modal.token_name'), with: 'Newest token' - all('input[type=checkbox]').each(&:click) - click_button I18n.t('projects.bots.index.bot_listing.generate_personal_access_token_modal.submit') end @@ -362,11 +452,19 @@ def setup end # confirm destroy bot - click_button I18n.t('bots.destroy_confirmation.submit_button') + assert_selector '#dialog' + within('#dialog') do + assert_text I18n.t('bots.destroy_confirmation.description', bot_name: @project_bot.user.email) + click_button I18n.t('bots.destroy_confirmation.submit_button') + end ### ACTIONS END ### ### VERIFY START ### - # PAT panel no longer present + # confirm bot destroyed + assert_text strip_tags(I18n.t(:'viral.pagy.limit_component.summary', from: 1, to: 20, count: 20, + locale: @user.locale)) + # PAT panel no longer contains content + assert_selector '#access-token-section' assert_no_selector '#access-token-section div' ### VERIFY END ### end diff --git a/test/system/projects/samples_test.rb b/test/system/projects/samples_test.rb index 40d9eeab5a..7f3b9878cd 100644 --- a/test/system/projects/samples_test.rb +++ b/test/system/projects/samples_test.rb @@ -481,6 +481,7 @@ class SamplesTest < ApplicationSystemTestCase # select all 3 samples click_button I18n.t(:'projects.samples.index.select_all_button') click_link I18n.t('projects.samples.index.transfer_button') + assert_selector '#dialog' within('#dialog') do within('#list_selections') do samples.each do |sample| @@ -529,7 +530,10 @@ class SamplesTest < ApplicationSystemTestCase Capybara.execute_script 'sessionStorage.clear()' # launch transfer dialog click_link I18n.t('projects.samples.index.transfer_button') + + assert_selector '#dialog' within('#dialog') do + assert_text I18n.t('projects.samples.transfers.dialog.title') find('input#select2-input').click find("button[data-viral--select2-value-param='#{@project2.id}']").click click_on I18n.t('projects.samples.transfers.dialog.submit_button') @@ -565,6 +569,8 @@ class SamplesTest < ApplicationSystemTestCase ### ACTIONS START ### click_button I18n.t(:'projects.samples.index.select_all_button') click_link I18n.t('projects.samples.index.transfer_button') + + assert_selector '#dialog' within('#dialog') do within('#list_selections') do samples.each do |sample| @@ -657,6 +663,8 @@ class SamplesTest < ApplicationSystemTestCase # transfer sample click_link I18n.t('projects.samples.index.transfer_button') + + assert_selector '#dialog' within('#dialog') do within('#list_selections') do # additional asserts to help prevent select2 actions below from flaking @@ -703,6 +711,7 @@ class SamplesTest < ApplicationSystemTestCase # launch dialog click_link I18n.t('projects.samples.index.transfer_button') + assert_selector '#dialog' within('#dialog') do # fill destination input find('input#select2-input').fill_in with: 'invalid project name or puid' @@ -1589,6 +1598,7 @@ class SamplesTest < ApplicationSystemTestCase find("input#sample_#{@sample2.id}").click end click_link I18n.t('projects.samples.index.clone_button') + assert_selector '#dialog' within('#dialog') do within('#list_selections') do # additional asserts to help prevent select2 actions below from flaking @@ -1639,7 +1649,10 @@ class SamplesTest < ApplicationSystemTestCase # clear localstorage Capybara.execute_script 'sessionStorage.clear()' click_link I18n.t('projects.samples.index.clone_button') + + assert_selector '#dialog' within('#dialog') do + assert_text I18n.t('projects.samples.clones.dialog.title') find('input#select2-input').click find("button[data-viral--select2-value-param='#{@project2.id}']").click click_on I18n.t('projects.samples.clones.dialog.submit_button') @@ -1679,6 +1692,7 @@ class SamplesTest < ApplicationSystemTestCase ### ACTIONS START ### click_button I18n.t(:'projects.samples.index.select_all_button') click_link I18n.t('projects.samples.index.clone_button') + assert_selector '#dialog' within('#dialog') do within('#list_selections') do samples.each do |sample| @@ -1724,6 +1738,7 @@ class SamplesTest < ApplicationSystemTestCase ### ACTIONS START #### click_button I18n.t(:'projects.samples.index.select_all_button') click_link I18n.t('projects.samples.index.clone_button') + assert_selector '#dialog' within('#dialog') do find('input#select2-input').fill_in with: 'invalid project name or puid' ### ACTIONS END ### @@ -1786,6 +1801,8 @@ class SamplesTest < ApplicationSystemTestCase # clone sample click_link I18n.t('projects.samples.index.clone_button') + + assert_selector '#dialog' within('#dialog') do within('#list_selections') do # additional asserts to help prevent select2 actions below from flaking