From f2a73b1e41cfcd094b6afa860dbe13872b12a3e2 Mon Sep 17 00:00:00 2001 From: Seth Horsley Date: Thu, 14 Nov 2024 01:18:39 +0100 Subject: [PATCH 1/3] add e2e tests --- .github/workflows/ci.yml | 15 ++ .gitignore | 6 + Gemfile.lock | 23 ++- esbuild.config.mjs | 12 ++ package.json | 9 +- playwright.config.js | 79 ++++++++ ruby_ui.gemspec | 2 + test/public/css/main.css | 71 +++++++ test/public/js/main.js | 73 +++++++ .../ruby_ui/alert_dialog/alert_dialog.spec.js | 117 +++++++++++ .../alert_dialog_spec.rb} | 12 +- .../ruby_ui/alert_dialog/alert_dialog_test.rb | 19 ++ test/test_helper.rb | 10 + test/test_server.rb | 77 +++++++ test/views/index.erb | 6 + yarn.lock | 188 ++++++++++++++++++ 16 files changed, 707 insertions(+), 12 deletions(-) create mode 100644 esbuild.config.mjs create mode 100644 playwright.config.js create mode 100644 test/public/css/main.css create mode 100644 test/public/js/main.js create mode 100644 test/ruby_ui/alert_dialog/alert_dialog.spec.js rename test/ruby_ui/{alert_dialog_test.rb => alert_dialog/alert_dialog_spec.rb} (75%) create mode 100644 test/ruby_ui/alert_dialog/alert_dialog_test.rb create mode 100644 test/test_server.rb create mode 100644 test/views/index.erb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed1f3ac7..119d511b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,5 +27,20 @@ jobs: - name: Run tests run: bundle exec rake test + - name: Install dependencies + run: npm install -g yarn && yarn + - name: Install Playwright Browsers + run: yarn playwright install --with-deps + + - name: Run e2e tests + run: yarn install --check-files && yarn test + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + - name: Run linter run: bundle exec rake standard diff --git a/.gitignore b/.gitignore index 7948b668..f7f64d8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ .DS_Store node_modules /app/assets/builds/* +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +dist +test/public/js/ruby_ui* diff --git a/Gemfile.lock b/Gemfile.lock index 61fc0f0a..afb242c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,17 +10,29 @@ GEM remote: https://rubygems.org/ specs: ast (2.4.2) + base64 (0.2.0) json (2.8.0) language_server-protocol (3.17.0.3) lint_roller (1.1.0) lru_redux (1.1.0) minitest (5.25.1) + mustermann (3.0.3) + ruby2_keywords (~> 0.0.1) + nio4r (2.7.4) parallel (1.26.3) parser (3.3.6.0) ast (~> 2.4.1) racc phlex (2.0.0.beta2) + puma (6.4.3) + nio4r (~> 2.0) racc (1.8.1) + rack (3.1.8) + rack-protection (4.0.0) + base64 (>= 0.1.0) + rack (>= 3.0.0, < 4) + rack-session (2.0.0) + rack (>= 3.0.0) rainbow (3.1.1) rake (13.2.1) regexp_parser (2.9.2) @@ -41,6 +53,13 @@ GEM rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + sinatra (4.0.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.0.0) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) standard (1.41.1) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) @@ -55,16 +74,18 @@ GEM rubocop-performance (~> 1.22.0) tailwind_merge (0.13.2) lru_redux (~> 1.1) + tilt (2.4.0) unicode-display_width (2.6.0) PLATFORMS arm64-darwin-24 - ruby DEPENDENCIES minitest (~> 5.0) + puma rake (~> 13.0) ruby_ui! + sinatra standard (~> 1.0) BUNDLED WITH diff --git a/esbuild.config.mjs b/esbuild.config.mjs new file mode 100644 index 00000000..51f39ed2 --- /dev/null +++ b/esbuild.config.mjs @@ -0,0 +1,12 @@ +import * as esbuild from "esbuild"; + +await esbuild.build({ + entryPoints: ["lib/ruby_ui/index.js"], + bundle: true, + minify: false, + sourcemap: true, + target: ["es2015"], + outfile: "dist/ruby_ui_js.min.js", + format: "iife", + globalName: "RubyUI", +}); diff --git a/package.json b/package.json index b9f31a4f..e28b7f3d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "description": "Stimulus controllers for ruby_ui Component Library", "homepage": "https://ruby_ui.dev", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "node esbuild.config.mjs", + "test": "playwright test" }, "keywords": [ "ruby_ui", @@ -34,6 +35,10 @@ "tippy.js": "^6.3.7" }, "devDependencies": { - "globals": "^15.8.0" + "@playwright/test": "^1.48.2", + "@types/node": "^22.9.0", + "esbuild": "^0.24.0", + "globals": "^15.8.0", + "playwright": "^1.48.2" } } diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 00000000..f8de9e93 --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,79 @@ +// @ts-check +const { defineConfig, devices } = require("@playwright/test"); + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config({ path: path.resolve(__dirname, '.env') }); + +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = defineConfig({ + testDir: "./test/ruby_ui", + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: "html", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + // headless: false, + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + + { + name: "firefox", + use: { ...devices["Desktop Firefox"] }, + }, + + { + name: "webkit", + use: { ...devices["Desktop Safari"] }, + }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: "ruby test/test_server.rb", + url: "http://127.0.0.1:4567", + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/ruby_ui.gemspec b/ruby_ui.gemspec index d078793a..c549e3a0 100644 --- a/ruby_ui.gemspec +++ b/ruby_ui.gemspec @@ -22,4 +22,6 @@ Gem::Specification.new do |s| s.add_development_dependency "rake", "~> 13.0" s.add_development_dependency "standard", "~> 1.0" s.add_development_dependency "minitest", "~> 5.0" + s.add_development_dependency "sinatra" + s.add_development_dependency "puma" end diff --git a/test/public/css/main.css b/test/public/css/main.css new file mode 100644 index 00000000..765ac575 --- /dev/null +++ b/test/public/css/main.css @@ -0,0 +1,71 @@ +:root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 5.9% 10%; + --radius: 0.5rem; + + /* ruby_ui especific */ + --warning: 38 92% 50%; + --warning-foreground: 0 0% 100%; + --success: 87 100% 37%; + --success-foreground: 0 0% 100%; +} + +.dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + + /* ruby_ui especific */ + --warning: 38 92% 50%; + --warning-foreground: 0 0% 100%; + --success: 84 81% 44%; + --success-foreground: 0 0% 100%; +} + +* { + @apply border-border; +} +body { + @apply bg-background text-foreground; + font-feature-settings: + "rlig" 1, + "calt" 1; + + /* docs specific */ + /* https://css-tricks.com/snippets/css/system-font-stack/ */ + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, + Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +} diff --git a/test/public/js/main.js b/test/public/js/main.js new file mode 100644 index 00000000..f4dff4ed --- /dev/null +++ b/test/public/js/main.js @@ -0,0 +1,73 @@ +const application = Stimulus.Application.start(); + +// Initialize Ruby UI with the Stimulus application +RubyUI.initialize(application); + +// const defaultTheme = require('tailwindcss/defaultTheme') + +tailwind.config = { + darkMode: ["class"], + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + warning: { + DEFAULT: "hsl(var(--warning))", + foreground: "hsl(var(--warning-foreground))", + }, + success: { + DEFAULT: "hsl(var(--success))", + foreground: "hsl(var(--success-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + // Font family without require + fontFamily: { + sans: ["var(--font-sans)", "ui-sans-serif", "system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif"], + }, + }, + }, +} diff --git a/test/ruby_ui/alert_dialog/alert_dialog.spec.js b/test/ruby_ui/alert_dialog/alert_dialog.spec.js new file mode 100644 index 00000000..5aaa565f --- /dev/null +++ b/test/ruby_ui/alert_dialog/alert_dialog.spec.js @@ -0,0 +1,117 @@ +import { test, expect } from "@playwright/test"; + +test.describe("AlertDialog", () => { + test("has all required elements and functions correctly", async ({ + page, + }) => { + await page.goto("http://localhost:4567/component/alert_dialog"); + + // Check if the trigger button exists and has correct text + const triggerButton = page.locator( + '[data-action="click->ruby-ui--alert-dialog#open"] button', + ); + await expect(triggerButton).toBeVisible(); + await expect(triggerButton).toHaveText("Show dialog"); + + // Ensure the dialog is initially hidden + const dialog = page.locator('div[role="alertdialog"]'); + await expect(dialog).toBeHidden(); + + // Click the trigger to open the dialog + await triggerButton.click(); + + // Ensure the dialog is now visible + await expect(dialog).toBeVisible(); + + // Check dialog content + await expect(dialog.locator("h2")).toBeVisible(); + await expect(dialog.locator("h2")).toHaveText("Are you absolutely sure?"); + + // Check description text + const description = dialog.locator("p.text-muted-foreground"); + await expect(description).toBeVisible(); + await expect(description).toHaveText( + "This action cannot be undone. This will permanently delete your account and remove your data from our servers.", + ); + + // Check dialog buttons + const cancelButton = dialog.locator( + 'button[data-action="click->ruby-ui--alert-dialog#dismiss"]', + ); + const continueButton = dialog.locator('button:text("Continue")'); + + await expect(cancelButton).toBeVisible(); + await expect(cancelButton).toHaveText("Cancel"); + await expect(continueButton).toBeVisible(); + await expect(continueButton).toHaveText("Continue"); + + // Check backdrop exists - Using data-state attribute instead of class + const backdrop = page.locator( + 'div[data-state="open"][data-aria-hidden="true"]', + ); + await expect(backdrop).toBeVisible(); + + // Test dismiss functionality + await cancelButton.click(); + await expect(dialog).toBeHidden(); + + // Test reopening + await triggerButton.click(); + await expect(dialog).toBeVisible(); + + // Finally dismiss again + await cancelButton.click(); + await expect(dialog).toBeHidden(); + }); + + test("dialog maintains correct state after multiple opens/closes", async ({ + page, + }) => { + await page.goto("http://localhost:4567/component/alert_dialog"); + + const triggerButton = page.locator( + '[data-action="click->ruby-ui--alert-dialog#open"] button', + ); + const dialog = page.locator('div[role="alertdialog"]'); + + // Test multiple open/close cycles + for (let i = 0; i < 3; i++) { + await expect(dialog).toBeHidden(); + await triggerButton.click(); + await expect(dialog).toBeVisible(); + await page + .locator('button[data-action="click->ruby-ui--alert-dialog#dismiss"]') + .click(); + await expect(dialog).toBeHidden(); + } + }); + + test("dialog buttons have correct attributes and styling", async ({ + page, + }) => { + await page.goto("http://localhost:4567/component/alert_dialog"); + + await page + .locator('[data-action="click->ruby-ui--alert-dialog#open"] button') + .click(); + + const cancelButton = page.locator( + 'button[data-action="click->ruby-ui--alert-dialog#dismiss"]', + ); + const continueButton = page.locator('button:text("Continue")'); + + // Check button attributes + await expect(cancelButton).toHaveAttribute("type", "button"); + await expect(continueButton).toHaveAttribute("type", "button"); + + // Check basic styling classes + await expect(cancelButton).toHaveAttribute( + "class", + expect.stringContaining("bg-background"), + ); + await expect(continueButton).toHaveAttribute( + "class", + expect.stringContaining("bg-primary"), + ); + }); +}); diff --git a/test/ruby_ui/alert_dialog_test.rb b/test/ruby_ui/alert_dialog/alert_dialog_spec.rb similarity index 75% rename from test/ruby_ui/alert_dialog_test.rb rename to test/ruby_ui/alert_dialog/alert_dialog_spec.rb index acb61f33..44c3cf85 100644 --- a/test/ruby_ui/alert_dialog_test.rb +++ b/test/ruby_ui/alert_dialog/alert_dialog_spec.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -require "test_helper" - -class RubyUI::AlertDialogTest < Minitest::Test - include Phlex::Testing::ViewHelper - - def test_render_with_all_items - output = phlex_context do +class RubyUI::AlertDialogSpec + def spec(context) + context.instance_exec do RubyUI.AlertDialog do RubyUI.AlertDialogTrigger do RubyUI.Button { "Show dialog" } @@ -23,7 +19,5 @@ def test_render_with_all_items end end end - - assert_match(/Show dialog/, output) end end diff --git a/test/ruby_ui/alert_dialog/alert_dialog_test.rb b/test/ruby_ui/alert_dialog/alert_dialog_test.rb new file mode 100644 index 00000000..a306e53c --- /dev/null +++ b/test/ruby_ui/alert_dialog/alert_dialog_test.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require "test_helper" +require_relative "alert_dialog_spec" + +class RubyUI::AlertDialogTest < Minitest::Test + include Phlex::Testing::ViewHelper + + def setup + @spec = RubyUI::AlertDialogSpec.new + end + + def test_render_with_all_items + output = phlex_context do + @spec.spec(self) + end + assert_match(/Show dialog/, output) + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 87803a86..42791337 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -36,6 +36,16 @@ def view_context ViewHelper = Basic end +# Add this to the end of your test/test_helper.rb file + +def load_spec(spec_path) + module_name = File.basename(spec_path, ".rb").split("_").map(&:capitalize).join + mod = Module.new + mod.module_eval(File.read(spec_path), spec_path) + Object.const_set(module_name, mod) + mod +end + # this is a tracepoint that will output the path of all files loaded that contain the string "phlex" # trace = TracePoint.new(:class) do |tp| # puts "Loaded: #{tp.path}" if tp.path.include?("phlex") diff --git a/test/test_server.rb b/test/test_server.rb new file mode 100644 index 00000000..ef6ce05a --- /dev/null +++ b/test/test_server.rb @@ -0,0 +1,77 @@ +require "sinatra" +require "phlex" +require_relative "../lib/ruby_ui" + +def copy_dist_to_public_js + dist_dir = File.expand_path("../../dist", __FILE__) + public_js_dir = File.join(settings.public_folder, "js") + + # Create the public/js directory if it doesn't exist + FileUtils.mkdir_p(public_js_dir) unless File.directory?(public_js_dir) + + if File.directory?(dist_dir) + # Copy all files from dist to public/js + FileUtils.cp_r(File.join(dist_dir, "."), public_js_dir) + puts "Copied all files from dist to public/js directory" + else + puts "Warning: dist directory not found" + end +end + +copy_dist_to_public_js + +class TestContext < Phlex::HTML + def view_template(&) + doctype + + html do + head do + script src: "https://unpkg.com/@hotwired/stimulus/dist/stimulus.umd.js" + script src: "https://cdn.tailwindcss.com" + # script src: "https://cdn.jsdelivr.net/npm/tailwindcss-animate@1.0.7/index.js" + script src: "/js/ruby_ui_js.min.js" + link rel: "stylesheet", href: "/css/main.css", as: "style" + script src: "/js/main.js", type: "module" + end + body do + div(&) + end + end + end +end + +def phlex_context(&) + TestContext.new.call(&) +end + +# Load all your components +# Dir["#{File.dirname(__FILE__)}/ruby_ui/*/*_spec.rb"].each { |file| require file } +# Dir["#{File.dirname(__FILE__)}/ruby_ui/*/*_spec.rb"].each do |file| +# require File +# end + +require_relative "ruby_ui/alert_dialog/alert_dialog_spec" +# binding.irb +# Set up Sinatra +set :public_folder, File.dirname(__FILE__) + "/public" +set :views, File.dirname(__FILE__) + "/views" + +# Define routes to render your components +get "/" do + erb :index +end + +get "/component/alert_dialog" do + phlex_context do + RubyUI::AlertDialogSpec.new.spec(self) + end +end + +get "/component/:name" do + component_name = params[:name].capitalize + component_class = Object.const_get("RubyUI::#{component_name}") + component = component_class.new + component.call +end + +# Add more routes as needed for different components or scenarios diff --git a/test/views/index.erb b/test/views/index.erb new file mode 100644 index 00000000..b7d71e9b --- /dev/null +++ b/test/views/index.erb @@ -0,0 +1,6 @@ +

RubyUI Component Tests

+ diff --git a/yarn.lock b/yarn.lock index 4a1b700a..d52c0a62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,126 @@ dependencies: regenerator-runtime "^0.14.0" +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== + "@floating-ui/core@^1.6.0": version "1.6.5" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.5.tgz#102335cac0d22035b04d70ca5ff092d2d1a26f2b" @@ -92,11 +212,25 @@ hey-listen "^1.0.8" tslib "^2.3.1" +"@playwright/test@^1.48.2": + version "1.48.2" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.48.2.tgz#87dd40633f980872283404c8142a65744d3f13d6" + integrity sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw== + dependencies: + playwright "1.48.2" + "@popperjs/core@^2.9.0": version "2.11.8" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@types/node@^22.9.0": + version "22.9.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.0.tgz#b7f16e5c3384788542c72dc3d561a7ceae2c0365" + integrity sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ== + dependencies: + undici-types "~6.19.8" + chart.js@^4.4.1: version "4.4.3" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.3.tgz#3b2e11e7010fefa99b07d0349236f5098e5226ad" @@ -111,6 +245,41 @@ date-fns@^2.30.0: dependencies: "@babel/runtime" "^7.21.0" +esbuild@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" + +fsevents@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fuse.js@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2" @@ -146,6 +315,20 @@ mustache@^4.2.0: resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== +playwright-core@1.48.2: + version "1.48.2" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.48.2.tgz#cd76ed8af61690edef5c05c64721c26a8db2f3d7" + integrity sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA== + +playwright@1.48.2, playwright@^1.48.2: + version "1.48.2" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.48.2.tgz#fca45ae8abdc34835c715718072aaff7e305167e" + integrity sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ== + dependencies: + playwright-core "1.48.2" + optionalDependencies: + fsevents "2.3.2" + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -162,3 +345,8 @@ tslib@^2.3.1: version "2.6.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + +undici-types@~6.19.8: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== From 4e7673f42814847d91bf9a38edde112a45a6c245 Mon Sep 17 00:00:00 2001 From: Seth Horsley Date: Thu, 14 Nov 2024 01:36:13 +0100 Subject: [PATCH 2/3] add linux support for ci --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index afb242c0..4960b808 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,6 +79,7 @@ GEM PLATFORMS arm64-darwin-24 + x86_64-linux DEPENDENCIES minitest (~> 5.0) From 4fe0cb7d10fead9c669c6de0ccedb35a4ec4cfb6 Mon Sep 17 00:00:00 2001 From: Seth Horsley Date: Tue, 19 Nov 2024 01:13:19 +0100 Subject: [PATCH 3/3] hopefully tests are passing now --- .github/workflows/ci.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 119d511b..997a0f18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,16 +24,24 @@ jobs: bundler-cache: true rubygems: latest + - name: Install Ruby dependencies + run: | + gem install bundler + bundle install + - name: Run tests run: bundle exec rake test - - name: Install dependencies - run: npm install -g yarn && yarn + - name: Install Node dependencies + run: | + npm install -g yarn + yarn install --frozen-lockfile + - name: Install Playwright Browsers run: yarn playwright install --with-deps - name: Run e2e tests - run: yarn install --check-files && yarn test + run: yarn test - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }}