From 543268111f62c8b940883b1bb3b3cd5341e3a7c0 Mon Sep 17 00:00:00 2001 From: Laurence de Bruxelles Date: Wed, 13 May 2026 09:23:03 +0300 Subject: [PATCH 1/5] Add output of slowest tests to CI To help with comparing the time to run tests in CI and locally, add the `--profile` flag to the invocation of RSpec in the test workflow. Note that this shouldn't affect the actual runtime of the tests, because RSpec always records this information; the `--profile` flag just determines whether it is printed at the end or not [[1]]. [1]: https://github.com/rspec/rspec/blob/6687661ab4267307f89053b097d91155bed5dcbd/rspec-core/lib/rspec/core/example.rb#L284 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b7c0a5fdf..a8c68aa1d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,7 +56,7 @@ jobs: run: bin/rails db:schema:load # Add or replace test runners here - name: Run Ruby tests - run: bundle exec rspec + run: bundle exec rspec --profile - name: Run JS tests run: npm test # Add or replace any other lints here From 74310b9196c6d8b210115951d605da8cb4c43cd3 Mon Sep 17 00:00:00 2001 From: Laurence de Bruxelles Date: Tue, 12 May 2026 10:59:19 +0300 Subject: [PATCH 2/5] Add workaround for slow specs due to ViteRuby On my machine (macOS Tahoe 26.4.1) when running request specs there are random delays that cause individual examples to sometimes take longer than 5 seconds. Profiling the specs showed that the `ViteRuby#dev_server_running?` check which occurs whenever a request is made was being held up by hostname resolution in the call to `Socket.tcp`. By default the dev server host is `localhost`; it is not clear why resolving localhost can sometimes be slow, it may be related to macOS/Bonjour, or something about the system configuration. Other developers have reported similar delays however. This commit adds a workaround, by changing the Vite configuration for the test profile to a hardcoded IP address, we remove the need for host resolution and the delay. This change doesn't make much of a difference to the total runtime of a complete test run, as a percentage of the total wall time, but does shave a little bit off, and also makes it easier to determine which tests are actually slow. Note: This delay occurs whether or not the dev server is running (it is not, for tests, unless run by the developer) and is unaffected by the configurable timeout delay in Vite. The delay was not present in CI because Vite is configured to assume that the dev server is not running in CI [1] without making a network call. [1]: https://github.com/ElMassimo/vite_ruby/blob/c6cf52a17199c50e7a09e3eea40f9a3d42986c0a/vite_ruby/lib/vite_ruby.rb#L110 --- config/vite.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config/vite.json b/config/vite.json index 7a12cb913..d8e3441ae 100644 --- a/config/vite.json +++ b/config/vite.json @@ -19,6 +19,7 @@ "autoBuild": true }, "test": { + "host": "::1", "port": 3037, "autoBuild": true } From 90ffbbbfdb1c7a17a80e52783a6598957b981a64 Mon Sep 17 00:00:00 2001 From: Laurence de Bruxelles Date: Mon, 11 May 2026 13:39:57 +0300 Subject: [PATCH 3/5] Mark all feature specs as slow Currently all our feature specs take over 1 second to run on my machine (MacBook Pro, Apple M1 Pro CPU, 16 GB RAM), as they rely on browser automation via headless Chrome. This commit adds a small bit of configuration to RSpec to add a `:slow` tag to all feature specs. This is partly for documentation purposes, but mainly it allows developers to skip slow specs when running tests locally with ``` rspec --tag ~slow ``` This change should not affect how the tests/PR checks run in CI. --- spec/support/mark_feature_specs_as_slow.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 spec/support/mark_feature_specs_as_slow.rb diff --git a/spec/support/mark_feature_specs_as_slow.rb b/spec/support/mark_feature_specs_as_slow.rb new file mode 100644 index 000000000..67d45e57e --- /dev/null +++ b/spec/support/mark_feature_specs_as_slow.rb @@ -0,0 +1,5 @@ +RSpec.configure do |config| + config.define_derived_metadata(type: :feature) do |metadata| + metadata[:slow] ||= true + end +end From 8b9ab19dbc94782bf2afebec679beb2ef44465c6 Mon Sep 17 00:00:00 2001 From: Laurence de Bruxelles Date: Thu, 7 May 2026 13:56:08 +0300 Subject: [PATCH 4/5] Mark specs as slow Mark examples/example groups that consistently take over a second to run on my machine (MacBook Pro, Apple M1 Pro CPU, 16 GB RAM) with the `:slow` tag. This is partly for documentation purposes, but mainly it allows developers to skip slow specs when running tests locally with ``` rspec --tag ~slow ``` This change should not affect how the tests/PR checks run in CI. Feature specs are not marked in this commit, as they are already marked as slow generally (see the previous commit). --- spec/i18n_spec.rb | 2 +- spec/requests/authentication_controller_spec.rb | 2 +- spec/views/pages/selection/options.html.erb_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb index 2db625160..108acc00a 100644 --- a/spec/i18n_spec.rb +++ b/spec/i18n_spec.rb @@ -2,7 +2,7 @@ require "i18n/tasks" -RSpec.describe I18n do +RSpec.describe I18n, :slow do let(:i18n) { I18n::Tasks::BaseTask.new } let(:missing_keys) { i18n.missing_keys } let(:unused_keys) { i18n.unused_keys } diff --git a/spec/requests/authentication_controller_spec.rb b/spec/requests/authentication_controller_spec.rb index 5c47afde7..826d046b2 100644 --- a/spec/requests/authentication_controller_spec.rb +++ b/spec/requests/authentication_controller_spec.rb @@ -83,7 +83,7 @@ def authenticate! GDS::SSO::Config.auth_valid_for = Settings.auth_valid_for end - it "re-authenticates after the configured time" do + it "re-authenticates after the configured time", :slow do login_as_standard_user get root_path diff --git a/spec/views/pages/selection/options.html.erb_spec.rb b/spec/views/pages/selection/options.html.erb_spec.rb index 0154a0811..38f28dc52 100644 --- a/spec/views/pages/selection/options.html.erb_spec.rb +++ b/spec/views/pages/selection/options.html.erb_spec.rb @@ -63,7 +63,7 @@ context "when there are fewer than 3000 options" do let(:selection_options) { (1..2999).to_a.map { |i| OpenStruct.new(name: i.to_s) } } - it "has an add another button" do + it "has an add another button", :slow do expect(rendered).to have_button(I18n.t("selection_options.add_another")) end @@ -75,7 +75,7 @@ context "when there are 3000 options" do let(:selection_options) { (1..3000).to_a.map { |i| OpenStruct.new(name: i.to_s) } } - it "does not have an add another button" do + it "does not have an add another button", :slow do expect(rendered).not_to have_button(I18n.t("selection_options.add_another")) end From e3d674cfff50f3382cb25f0052dcfab22013434e Mon Sep 17 00:00:00 2001 From: Laurence de Bruxelles Date: Mon, 11 May 2026 13:40:25 +0300 Subject: [PATCH 5/5] Speed up slow examples for selection options long list page The `button` selector in Capybara when a locator is provided is very complicated [1], and for these examples it was taking around 5 seconds each on my machine (MacBook Pro, Apple M1 Pro CPU, 16 GB RAM). [1]: https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector/definition/button.rb --- spec/views/pages/selection/options.html.erb_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/views/pages/selection/options.html.erb_spec.rb b/spec/views/pages/selection/options.html.erb_spec.rb index 38f28dc52..7fdccd836 100644 --- a/spec/views/pages/selection/options.html.erb_spec.rb +++ b/spec/views/pages/selection/options.html.erb_spec.rb @@ -63,8 +63,8 @@ context "when there are fewer than 3000 options" do let(:selection_options) { (1..2999).to_a.map { |i| OpenStruct.new(name: i.to_s) } } - it "has an add another button", :slow do - expect(rendered).to have_button(I18n.t("selection_options.add_another")) + it "has an add another button" do + expect(rendered).to have_button(text: I18n.t("selection_options.add_another")) end it "does not have inset text stating you cannot add more options" do @@ -75,8 +75,8 @@ context "when there are 3000 options" do let(:selection_options) { (1..3000).to_a.map { |i| OpenStruct.new(name: i.to_s) } } - it "does not have an add another button", :slow do - expect(rendered).not_to have_button(I18n.t("selection_options.add_another")) + it "does not have an add another button" do + expect(rendered).not_to have_button(text: I18n.t("selection_options.add_another")) end it "has inset text stating you cannot add more options" do