Fix flaky spec

failing spec: `spec/features/admin/enterprise/enterprise_spec.rb:130`
failing run: `https://github.com/opf/openproject/actions/runs/19163991005/job/54780241287?pr=20840`

Clicking on some elements in modals can fail as the click location is
wrong if the modal animation is not finished yet.

Fix the test by waiting for anmiation complete, and extract a page
object for enterprise tokens page to prevent repetition.
This commit is contained in:
Christophe Bliard
2025-11-10 10:51:30 +01:00
parent 8456e1a2e5
commit 4ee9ff58d8
5 changed files with 93 additions and 34 deletions
@@ -126,9 +126,7 @@ module Pages::Meetings
end
def expect_modal(...)
expect(page).to have_modal(...)
modal = find(:modal, ...)
wait_for_size_animation_completion(modal)
Components::Common::Modal.new.expect_modal(...)
end
def expect_no_add_form
@@ -127,7 +127,7 @@ module Pages::RecurringMeeting
end
def expect_modal(...)
expect(page).to have_modal(...)
Components::Common::Modal.new.expect_modal(...)
end
def expect_no_meeting(date:)
@@ -35,10 +35,12 @@ RSpec.describe "Enterprise token", :js do
shared_let(:admin) { create(:admin) }
let(:enterprise_tokens_page) { Pages::Admin::EnterpriseTokens::Index.new }
describe "EnterpriseToken management" do
before do
login_as admin
visit enterprise_tokens_path
enterprise_tokens_page.visit!
end
it "shows a teaser page and has a button to add a token with a dialog" do
@@ -53,14 +55,11 @@ RSpec.describe "Enterprise token", :js do
context "with invalid input" do
it "shows an error message" do
click_button "Add Enterprise token"
fill_in "Type support token text", with: "foobar"
click_button "Add"
enterprise_tokens_page.add_enterprise_token("foobar")
# The dialog is still open with an error message on token field
expect(page).to have_dialog("Add Enterprise token")
validation_error = "Enterprise support token can't be read. Are you sure it is a support token?"
expect(page).to have_field("Type support token text", validation_error:)
enterprise_tokens_page.expect_add_token_validation_error(validation_error)
end
end
@@ -74,19 +73,16 @@ RSpec.describe "Enterprise token", :js do
token.domain = Setting.host_name
end
end
let(:modals) { Components::Common::Modal.new }
before do
allow(OpenProject::Token).to receive(:import).and_return(token_object)
end
it "allows token import flow" do
click_button "Add Enterprise token"
fill_in "Type support token text", with: "foobar"
click_button "Add"
enterprise_tokens_page.add_enterprise_token("foobar")
expect(page).to have_text("Quick feature overview")
expect(page).to have_css("#enterprise-trial-welcome-dialog video")
page.find('[data-close-dialog-id="enterprise-trial-welcome-dialog"]').click
enterprise_tokens_page.close_welcome_video_modal
# Table headers
[
@@ -117,7 +113,7 @@ RSpec.describe "Enterprise token", :js do
wait_for_network_idle
# Expect deletion modal
expect(page).to have_dialog("Delete enterprise token")
modals.expect_modal("Delete enterprise token")
within_dialog("Delete enterprise token") do
click_button "Delete"
end
@@ -128,31 +124,22 @@ RSpec.describe "Enterprise token", :js do
end
it "cannot import same token twice" do
click_button "Add Enterprise token"
fill_in "Type support token text", with: "foobar"
click_button "Add"
enterprise_tokens_page.add_enterprise_token("foobar")
expect(page).to have_text("Quick feature overview")
expect(page).to have_css("#enterprise-trial-welcome-dialog video")
page.find('[data-close-dialog-id="enterprise-trial-welcome-dialog"]').click
enterprise_tokens_page.close_welcome_video_modal
click_button "Add Enterprise token"
fill_in "Type support token text", with: "foobar"
click_button "Add"
# Add the token a second time
enterprise_tokens_page.add_enterprise_token("foobar")
# The dialog is still open with an error message on token field
expect(page).to have_dialog("Add Enterprise token")
validation_error = "This token has already been added."
expect(page).to have_field("Type support token text", validation_error:)
enterprise_tokens_page.expect_add_token_validation_error("This token has already been added.")
# Try importing with blank spaces and newlines before and after
fill_in "Type support token text", with: " \nfoobar \n"
click_button "Add"
# The dialog is still open with an error message on token field
expect(page).to have_dialog("Add Enterprise token")
validation_error = "This token has already been added."
expect(page).to have_field("Type support token text", validation_error:)
enterprise_tokens_page.expect_add_token_validation_error("This token has already been added.")
end
end
end
+9 -2
View File
@@ -37,9 +37,16 @@ module Components
include Capybara::RSpecMatchers
include Flash::Expectations
include RSpec::Matchers
include WaitHelpers
def expect_title(text)
expect(page).to have_modal(text)
def expect_modal(title, wait: Capybara.default_max_wait_time)
expect_title(title, wait:)
modal = find(:modal, title, wait:)
wait_for_size_animation_completion(modal)
end
def expect_title(text, wait: Capybara.default_max_wait_time)
expect(page).to have_modal(text, wait:)
end
def expect_open
@@ -0,0 +1,67 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
require "support/pages/page"
module Pages
module Admin
module EnterpriseTokens
class Index < ::Pages::Page
def path
enterprise_tokens_path
end
def add_enterprise_token(token_text)
click_button "Add Enterprise token"
modals.expect_modal("Add Enterprise token")
fill_in "Type support token text", with: token_text
click_button "Add"
end
def close_welcome_video_modal
modals.expect_modal("Quick feature overview")
expect(page).to have_css("#enterprise-trial-welcome-dialog video")
page.find('[data-close-dialog-id="enterprise-trial-welcome-dialog"]').click
end
def expect_add_token_validation_error(message)
expect(page).to have_dialog("Add Enterprise token")
expect(page).to have_field("Type support token text", validation_error: message)
end
private
def modals
Components::Common::Modal.new
end
end
end
end
end