Skip to content

Running Challenges on iPhone!#2

Merged
johnsyweb merged 86 commits into
masterfrom
paj/refactorings
Mar 6, 2026
Merged

Running Challenges on iPhone!#2
johnsyweb merged 86 commits into
masterfrom
paj/refactorings

Conversation

@johnsyweb
Copy link
Copy Markdown
Owner

@johnsyweb johnsyweb commented Mar 5, 2026

Context

parkrun's official app is nice, and all, but there are some views on my data that I really quite like from this little extension. I'd actually quite like to have a Userscript version of this to reduce the cycle time between tweaks and running in the browser (Safari, mostly). So I dusted off the repository and tried to remember how everything fitted together. I realised that there were some things I could simplify to make the SDLC more responsive. Like having a src/ directory that represents the common case and allows running unit tests. And using mocks rather than firing up Nginx instances to test the UI.

After all that, bundling a Userscript was relatively straightforward.

Change

See individual commits for finer details.

Confirmation

Considerations

I don't expect this will get merged to the origin, but who knows?

```
Error: This request has been automatically failed because it uses a deprecated version of `actions/cache: v2`. Please update your workflow to use v3/v4 of actions/cache to avoid interruptions. Learn more: https://github.blog/changelog/2024-12-05-notice-of-upcoming-releases-and-breaking-changes-for-github-actions/#actions-cache-v1-v2-and-actions-toolkit-cache-package-closing-down
```
…ripts and CI

- Add scripts/build-extension.mjs: copy src, merge manifests, apply patches,
  run web-ext build for Chrome and Firefox; output to existing build dirs
- script/update and script/setup source build/version.sh and run
  pnpm --filter running-challenges-extension run build:extension (with mise)
- CI: single build job runs Node build with EXTENSION_BUILD_ID, uploads
  chrome and firefox artifacts
- Remove build/extension-chrome/build.sh and build/extension-firefox/build.sh
- build_all.sh now invokes pnpm build; README and pnpm-migration.md updated
- Add browser-extensions/extension/src/js/tests as workspace package
  running-challenges-tests in pnpm-workspace.yaml
- script/test runs pnpm --filter running-challenges-tests run test-with-coverage
  (with mise); script/bootstrap no longer runs npm install in tests dir
- Remove tests package-lock.json; single pnpm-lock.yaml at root
- Dependabot: pnpm at / for workspace; keep npm for ui-test
- README and pnpm-migration.md updated
…dored

- Add extension deps: jquery, leaflet, leaflet.fullscreen, leaflet.markercluster,
  leaflet-extra-markers, d3-voronoi (pinned versions)
- Build copies third-party JS from extension node_modules; CSS that is patched
  for extension URLs (leaflet, leaflet-fullscreen, leaflet-extramarkers) and
  leaflet-markercluster CSS from npm; leaflet-canvasicon and leaflet-piechart
  remain vendored
- Manifest: use leaflet-fullscreen-1.1.0.js, leaflet-extramarkers-1.0.6.js
- Unit tests: add jquery to running-challenges-tests, require('jquery')
- Remove vendored js/lib/third-party (jquery, leaflet, plugins, d3-voronoi) and
  css/third-party/leaflet-markercluster; update pnpm-migration.md and README
- Use plugin API L.control.fullscreen().addTo(r_map) instead of
  new L.Control.Fullscreen() so it matches leaflet.fullscreen
- Remove undefined data reference from handle_error to avoid masking
  real errors with ReferenceError
…arget the actual control element (.leaflet-control-zoom-fullscreen) instead of\n a descendant anchor so the background sprite is applied\n- Remove now-unnecessary browser-specific CSS patches for fullscreen icons;\n build copies the images into the extension and relative URLs work
… copy\n\n- Stop copying our own css/third-party/leaflet-fullscreen into the build; use\n Control.FullScreen.css and icons from the leaflet.fullscreen npm package\n- Update manifest to reference css/third-party/leaflet-fullscreen/Control.FullScreen.css\n- Remove the now-unnecessary first-party leaflet-fullscreen.css from the repo\n and update pnpm-migration notes accordingly
…rt Chromium with web-ext in the background so it doesn't block\n- Keep Firefox as the foreground web-ext run for the same parkrun URL\n- Share local node_modules/.bin for consistent web-ext resolution
…mages from npm\n\n- script/test now runs Playwright UI tests after unit coverage, so ./script/test\n exercises both node tests and Chrome UI flows\n- ui-test package.json wired with "test" script (playwright test) and new\n assertions for fullscreen control icon and Leaflet marker icons\n- build-extension.mjs copies leaflet.css and its dist images from node_modules\n instead of relying on vendored css/third-party/leaflet; remove legacy\n Leaflet CSS patch files\n- README updated to describe the expanded behaviour of ./script/test
…etwork)

- Add getFixturePath, mockParkrunRunnerPage, mockEventsJson to serve
  fixtures so the test does not hit live parkrun or images.parkrun.com
- New test 'Leaflet markers load with icons (no network)' loads a
  mocked runner page and events.json, then asserts the explorer map
  has at least one visible .leaflet-marker-icon
- Ignore extension-binaries/ and test-artifacts/ in ui-test .gitignore
- Add installNetworkFreeMocks() that routes all requests: fulfill main doc,
  volunteer URL, events.json, and OSM tiles from fixtures; abort everything else
- Add volunteer fixture path and 1px PNG stub for tile.openstreetmap.org
- Use waitUntil: domcontentloaded and single route so test needs no network
  and completes in ~1.7s
- Set headless: true, devtools: false
- Add channel: 'chromium' and --headless=new so extension content
  scripts run in headless mode
- Use installNetworkFreeMocks and domcontentloaded; remove fixed timeout and screenshot
… fast

- Use installNetworkFreeMocks for athlete 999999 and domcontentloaded
- Unroute and installNetworkFreeMocks per parkrunnerId before each goto
- Use domcontentloaded and 15s timeout for message div
- Remove unused mockParkrunRunnerPage and mockEventsJson (all tests use installNetworkFreeMocks)
- Remove commented-out import and redundant comments
- Update installNetworkFreeMocks JSDoc; use const for badge maps
- Stop tracking and delete ui-test/screenshot.png
- Ignore screenshot*.png in ui-test/.gitignore
- Remove screenshot.png from CI upload-artifact (keep playwright-report only)
- pnpm-migration.md: note that Playwright UI tests (especially Leaflet
  markers test) run in CI and catch regressions when moving Leaflet to pnpm
- build-extension.yml: comment that full suite guards third-party migrations
- Network-free UI tests (installNetworkFreeMocks, catch-all abort)
- Headless run with channel chromium and --headless=new
- Removed disused code/comments and screenshot ephemera
- Docs: UI tests guard Leaflet-to-pnpm migration
- Resolve conflicts by keeping leaflet-markers-ui-test spec; drop
  Explorer map fullscreen test (selector not found in headless, can re-add later)
johnsyweb added 23 commits March 5, 2026 19:42
- When options don’t specify athlete_number, use the current parkrunner page id
- When home_parkrun_info is missing, derive it as the most frequently visited event using results + geo data
- Treat the page as "our page" when the visible id matches the effective athlete id
- Remove the old N.B. message about setting home parkrun and athlete id in options
- Infer athlete_number from the current parkrunner page when options are unset
- Infer home_parkrun_info as the most frequently visited event, breaking ties
  in favour of the most recently visited event
- Remove the old note about needing to set athlete id and home parkrun in options
- Add Playwright test that loads a network-mocked parkrunner profile and
  checks for canvas.leaflet-piechart-icon elements on the explorer map
- Ensures the leaflet-piechart integration doesn’t silently regress
- Point country completion pie chart UI test at A482 (Danny Norman) on parkrun.org.uk
- This profile has substantial UK tourism (e.g. 474/868 events), ensuring a visible pie segment
- Drop brittle [title*='/'] marker selector and wait directly for
  canvas.leaflet-piechart-icon inside #explorer_map
- Keeps the test focused on the presence of piechart canvases without
  assuming how Leaflet renders marker titles/tooltips
Switch leaflet-piechart to the upstream commit that restores CanvasIcon styling, and update UI tests and test runner so Playwright always uses a freshly built Chrome extension.
- Force chrome.storage.local to localStorage shim in userscript build
- Expose i18n, cache, challenges and challenges_ui functions on window for IIFE bundle
- Normalise table caption whitespace when matching 'All Results'
- Add d3-bootstrap so window.d3.voronoi exists for challenges_ui
- In test: listen for events.json before goto, save console on any failure
…nd sprites

- Inject Leaflet ExtraMarkers CSS in userscript build and rewrite sprite
  URLs to unpkg so challenge maps (e.g. Pirates) show event markers
- Add Pirates challenge map test and fulfill ExtraMarkers image
  requests from node_modules in UI test
…ut fixes

- extension: add build:userscript script and esbuild devDependency
- script/update: run userscript bundle build
- challenges_ui: map div width 100%, reflow and invalidateSize for
  explorer/challenge maps so tiles and markers render correctly in
  userscript (e.g. in table layouts)
- website: add 'Install as a userscript' link on index
- mise.toml, .ruby-version: pin Ruby 3.2
- website/Gemfile: require ruby ">= 3.2.0"
- website/Gemfile.lock: resolve deps under 3.2
- README: document Ruby 3.2 and verify-website command

Verified: bundle install && bundle exec jekyll build and serve under 3.2.
Staging CI uses mise.toml so will pick up 3.2; production workflow unchanged.
- mise.toml: pin Ruby 3.3
- website/Gemfile: require ruby ">= 3.3.0"
- website/Gemfile.lock: resolved under Ruby 3.3.10
- README: document Ruby 3.3

Verified: bundle install && bundle exec jekyll build under 3.3.
mise.toml is the single source of truth for tool versions; .ruby-version was redundant.
- mise.toml: pin Ruby 3.4
- website/Gemfile: require ruby ">= 3.4.0"; add base64, bigdecimal, csv
  (Ruby 3.4 ships these as bundled gems, required by Jekyll)
- website/Gemfile.lock: resolved under Ruby 3.4.7
- README: document Ruby 3.4

Verified: bundle install && bundle exec jekyll build under 3.4.
- website/Gemfile: remove Jekyll boilerplate and redundant comments
- website/Gemfile.lock: BUNDLED WITH 2.6.1
…ension

- Playwright script loads Chrome extension and captures regions from live parkrun pages
- Group by URL to load each page once and take multiple clips (top/bottom selectors)
- Full-page screenshot with page-coordinate clip to avoid viewport issues
- Config in screenshots.yml; run via ./script/update-screenshots
- Add running_challenges_volunteer_challenges_heading id for volunteer section selector
- Give challenge map divs zero height when map not displayed
- add_table_break_row: optional id for section headings
- Website: userscript instructions and built userscript; index copy update
…Tampermonkey

- build/version.sh and build script fallbacks set to 2.0.1
- Userscript @Version uses EXTENSION_BUILD_VERSION only (no build ID) for x.y.z format
- Rebuild userscript bundle
- _data/userscript_managers.yml: Tampermonkey, Violentmonkey, Userscripts, Stay install URLs
- getstarted.md: userscript installation section with step-by-step and manager links
- index.md: link userscript managers by name on home page
- jekyll serve --host 0.0.0.0 so server listens on all interfaces
- script/server-website prints LAN URL when available (macOS ipconfig / Linux hostname -I)
@johnsyweb johnsyweb changed the title Refactorings... Running Challenges on iPhone! Mar 6, 2026
…hout SSH

CI fails with 'Permission denied (publickey)' when cloning github: specifier.
Switch to git+https://github.com/... in package.json and lockfile resolution.
…flow

copy-assets.sh reads from browser-extensions/extension/node_modules/;
add pnpm install --frozen-lockfile step so node_modules exists.
Deploy steps (checkout staging repo, reconcile branches, gh-pages deploy)
now run only when github.repository is fraz3alpha/running-challenges and
actor is not dependabot. Forks still run the full build but skip deploy.
… job

script/cibuild runs Playwright UI tests; Chromium was not installed in this
job, causing all 35 Playwright tests to fail in CI. Add the same
playwright install step used by the integration-test job.
- Set website/Gemfile.lock BUNDLED WITH to 2.6.9 for dev/CI consistency
- Add mise run bundle-install and bundle-update-bundler for website gems
@johnsyweb johnsyweb merged commit d525f58 into master Mar 6, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant