Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 10 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,16 @@ jobs:
- *restore_yarn_cache
- *run_yarn_install
- run:
name: Lint & Code styles
name: Format check
command: |
yarn run format:check && exit 0
echo ""
echo "=== Formatting violations (showing intended oxfmt output as diff) ==="
yarn oxfmt . > /dev/null
git --no-pager diff --color
exit 1
- run:
name: Lint
command: yarn run lint
- run:
name: Type Checking
Expand Down
34 changes: 29 additions & 5 deletions .claude/rules/e2e.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Test Locations and Frameworks

| Location | Framework | Purpose |
|----------|-----------|---------|
| --- | --- | --- |
| `tests/e2e/playwright/` | Playwright | Main e2e suite for all InstantSearch flavors |
| `tests/e2e/` (wdio files) | WebdriverIO | IE11 tests only (via Sauce Labs) |
| `packages/react-instantsearch-nextjs/__tests__/e2e/` | Playwright | App Router Next.js e2e tests |
Expand All @@ -14,6 +14,7 @@
### Main E2E Suite (Playwright)

**Prerequisites:** Examples must be built first:

```bash
yarn website:examples
```
Expand Down Expand Up @@ -86,49 +87,60 @@ test.describe('feature name', () => {
The `helpers` fixture provides these methods:

**RefinementList:**

- `clickRefinementListItem(label)` - Click a refinement list item
- `getSelectedRefinementListItem()` - Get the selected item's text

**SearchBox:**

- `setSearchBoxValue(value)` - Set the search input value
- `getSearchBoxValue()` - Get the current search value

**Hits:**

- `getHitsTitles()` - Get all hit titles as an array

**HierarchicalMenu:**

- `clickHierarchicalMenuItem(label)` - Click a menu item
- `getSelectedHierarchicalMenuItems()` - Get selected items

**RangeSlider:**

- `dragRangeSliderLowerBoundTo(value)` - Drag lower handle
- `dragRangeSliderUpperBoundTo(value)` - Drag upper handle
- `getRangeSliderLowerBoundValue()` - Get lower bound value
- `getRangeSliderUpperBoundValue()` - Get upper bound value

**Pagination:**

- `clickPage(n)` - Navigate to page n
- `clickNextPage()` - Go to next page
- `clickPreviousPage()` - Go to previous page
- `getCurrentPage()` - Get current page number

**ToggleRefinement:**

- `clickToggleRefinement()` - Toggle the refinement
- `getToggleRefinementStatus()` - Get checked status

**RatingMenu:**

- `clickRatingMenuItem(label)` - Click rating (e.g., "4 & up")
- `getSelectedRatingMenuItem()` - Get selected rating label

**SortBy:**

- `setSortByValue(label)` - Select sort option by label
- `getSortByValue()` - Get current sort value

**HitsPerPage:**

- `setHitsPerPage(label)` - Select hits per page
- `getHitsPerPage()` - Get current value

**ClearRefinements:**

- `clickClearRefinements()` - Click clear button

### Best Practices
Expand Down Expand Up @@ -156,13 +168,15 @@ The main e2e suite tests multiple InstantSearch flavors:
Tests run against example apps in `website/examples/{flavor}/e-commerce/`.

To run a single flavor:

```bash
E2E_FLAVOR=react yarn test:e2e
```

## IE11 Considerations

IE11 tests are kept in WebdriverIO because Playwright doesn't support IE11. These tests:

- Only run `js` and `js-umd` flavors
- Require Sauce Labs for remote IE11 browser
- Use the same test specs in `tests/e2e/specs/` and helpers in `tests/e2e/helpers/`
Expand All @@ -188,6 +202,7 @@ PWDEBUG=1 yarn workspace @instantsearch/e2e-tests test:playwright
### View Test Reports

After running tests, open the HTML report:

```bash
npx playwright show-report tests/e2e/playwright/playwright-report
```
Expand All @@ -203,15 +218,20 @@ npx playwright show-report tests/e2e/playwright/playwright-report
### Port conflicts on macOS

On macOS, port 5000 is used by AirPlay Receiver (ControlCenter). The tests use port 3456 instead. If you need to change the port, update:

- `tests/e2e/playwright/playwright.config.ts` (both `baseURL` and `webServer.command/url`)

### SPA routing not working

The e-commerce examples use History API routing (e.g., `/search/Appliances/`). The `website/serve.json` file configures rewrites for these routes. If you add new SPA routes, update this file:

```json
{
"rewrites": [
{ "source": "/examples/js/e-commerce/search/**", "destination": "/examples/js/e-commerce/index.html" }
{
"source": "/examples/js/e-commerce/search/**",
"destination": "/examples/js/e-commerce/index.html"
}
]
}
```
Expand All @@ -225,18 +245,21 @@ Tests have 1 retry locally and 2 retries in CI to handle occasional flakiness.
### Multiple elements matched

If you see "strict mode violation" errors about multiple elements:

- SearchBox selectors are scoped to the header to avoid matching RefinementList search inputs
- Use more specific selectors when targeting widgets that may appear multiple times

### Different HTML structures across flavors

The JS and React examples have different HTML structures:

- **JS examples**: Use `id="header"` and `data-widget="searchbox"` attributes
- **React examples**: Use `className="header"` (class instead of id) and render SearchBox directly inside header

The fixtures account for this with combined selectors like:

```typescript
'#header .ais-SearchBox [type=search], .header > .ais-SearchBox [type=search], [data-widget="searchbox"] .ais-SearchBox [type=search]'
'#header .ais-SearchBox [type=search], .header > .ais-SearchBox [type=search], [data-widget="searchbox"] .ais-SearchBox [type=search]';
```

If you add new selectors, ensure they work across all flavors.
Expand All @@ -254,6 +277,7 @@ When migrating tests from WebDriverIO to Playwright, be aware of these differenc

- **WebDriverIO**: `$('.ais-Hits-item')` returns first match, clicking works on container elements
- **Playwright**: `page.locator('.ais-Hits-item').first()` - clicking on container may not hit child link elements. Use `.locator('a')` to target links explicitly:

```typescript
// WebDriverIO
const link = await $('.ais-Hits-item');
Expand Down Expand Up @@ -289,10 +313,10 @@ This gives the browser enough time to process JavaScript events like popstate ha
## CI Integration

Tests run in CircleCI:

- **e2e tests playwright** - Main suite with Chromium + Firefox
- **e2e tests ie11** - IE11 via Sauce Labs
- **e2e tests router nextjs** - Pages Router Next.js tests
- **e2e tests app router nextjs** - App Router Next.js tests

JUnit reports are stored for test results visualization.
Playwright HTML reports are stored as artifacts.
JUnit reports are stored for test results visualization. Playwright HTML reports are stored as artifacts.
6 changes: 3 additions & 3 deletions .claude/skills/port-widget/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
interface:
display_name: "Port InstantSearch Widget"
short_description: "Port widgets across InstantSearch flavors"
default_prompt: "Use $port-widget to port a widget or connector-driven feature across the InstantSearch JavaScript, React, and Vue packages in this repo."
display_name: 'Port InstantSearch Widget'
short_description: 'Port widgets across InstantSearch flavors'
default_prompt: 'Use $port-widget to port a widget or connector-driven feature across the InstantSearch JavaScript, React, and Vue packages in this repo.'

policy:
allow_implicit_invocation: true
56 changes: 0 additions & 56 deletions .eslintignore

This file was deleted.

3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Introduced prettier
25cd787e6a06502ee3a85648f90f693276cca671

# Reformat with oxfmt
3e2abd41c28a6dec768ac7a2c3b531300d8bc62e
27 changes: 12 additions & 15 deletions .github/prompts/docs-automation.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
You are updating documentation for InstantSearch.

IMPORTANT: This is a non-interactive automated workflow. Do not ask for user input or clarification.
If you cannot access a file, skip it and work with what you have.
If there are no documentable changes, report that finding and exit successfully.
IMPORTANT: This is a non-interactive automated workflow. Do not ask for user input or clarification. If you cannot access a file, skip it and work with what you have. If there are no documentable changes, report that finding and exit successfully.

BE EFFICIENT: You have limited turns. Read multiple files in parallel when possible. Don't over-explore.

## Repository Layout

You are running from the root directory where:

- instantsearch/ contains the InstantSearch source code and changelogs
- docs-new/ contains the documentation repository to update

Expand All @@ -21,29 +20,31 @@ You are running from the root directory where:
- instantsearch/packages/vue-instantsearch/CHANGELOG.md (low priority - only update Vue docs if this changelog shows explicit feature additions)

2. Find and read ONE existing doc as a format reference:
- Use Glob to find InstantSearch widget docs: docs-new/**/instantsearch/**/*.mdx
- Use Glob to find InstantSearch widget docs: docs-new/**/instantsearch/**/\*.mdx
- Read just ONE example file to understand the format (don't read many)

3. Update documentation for any new features, modified components, or breaking changes.

4. After making changes, run link check to catch broken links:
- cd docs-new && npm run check:links
Fix any broken links you introduced, but don't spend time on pre-existing issues.
- cd docs-new && npm run check:links Fix any broken links you introduced, but don't spend time on pre-existing issues.

5. ## REQUIRED: Write a summary file at CHANGES_SUMMARY.md with this exact format:

Comment on lines 28 to +32

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numbered instructions here were collapsed in a way that hurts clarity and changes meaning (e.g., the check:links command and its explanation are merged into one bullet, and 5. ## REQUIRED: is an odd hybrid of list item + heading). Please reformat these steps back into clear bullets/lines so the automation prompt remains unambiguous.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was reformatted because of the --- being a header

5. REQUIRED: Write a summary file at CHANGES_SUMMARY.md with this exact format:
---
First line: A short title describing the main change (e.g., 'Add useFrequentlyBoughtTogether hook documentation')

Blank line, then a markdown list of what was changed:
- Added docs for X widget/hook
- Updated Y component with new Z prop
- Fixed broken links in W page
---

***

If no changes were made, write 'No documentation changes needed' as the title.

## Flavor Mapping

Each package has its own documentation flavor:

- instantsearch.js → .js.mdx files
- react-instantsearch → .react.mdx files
- vue-instantsearch → .vue.mdx files
Expand All @@ -57,12 +58,8 @@ Each package has its own documentation flavor:
- Match the existing documentation format and style exactly
- Only modify documentation files in docs-new/
- Don't add placeholder content - only document what actually exists
- CROSS-FLAVOR CONSISTENCY: When updating a widget/hook that exists in multiple flavors (JS, React, Vue),
check if the same prop/feature exists in the other flavors and update ALL relevant docs.
Many features are shared via instantsearch-ui-components. Read the source for each flavor to verify.
- CROSS-FLAVOR CONSISTENCY: When updating a widget/hook that exists in multiple flavors (JS, React, Vue), check if the same prop/feature exists in the other flavors and update ALL relevant docs. Many features are shared via instantsearch-ui-components. Read the source for each flavor to verify.

## Source Code Reference

The InstantSearch source is at instantsearch/ for reference.
Read source files to understand APIs, types, and implementation.
Example: instantsearch/packages/instantsearch.js/src/widgets/
The InstantSearch source is at instantsearch/ for reference. Read source files to understand APIs, types, and implementation. Example: instantsearch/packages/instantsearch.js/src/widgets/
4 changes: 2 additions & 2 deletions .github/scripts/architecture-refactor.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ function parseArgs(argv) {
inlineValue !== undefined
? inlineValue
: next && !next.startsWith('--')
? (index++, next)
: true;
? (index++, next)
: true;

options[name] = value;
}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docs-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ jobs:
runs-on: ubuntu-latest
# Only run on release commits (chore: release) or manual triggers
if: >-
github.event_name == 'workflow_dispatch' ||
(startsWith(github.event.head_commit.message, 'chore:') && contains(github.event.head_commit.message, 'release'))
github.event_name == 'workflow_dispatch' || (startsWith(github.event.head_commit.message, 'chore:') && contains(github.event.head_commit.message, 'release'))


steps:
- name: Checkout instantsearch
Expand Down
18 changes: 2 additions & 16 deletions .github/workflows/pkg-pr-new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,5 @@ jobs:

- name: Publish preview packages
run: >
npx pkg-pr-new publish
--compact
--template './examples/js/getting-started'
--template './examples/react/getting-started'
--template './examples/react/next-app-router'
--template './examples/react/next-routing'
--template './examples/vue/getting-started'
'./packages/algoliasearch-helper'
'./packages/instantsearch.js'
'./packages/react-instantsearch'
'./packages/react-instantsearch-core'
'./packages/react-instantsearch-nextjs'
'./packages/react-instantsearch-router-nextjs'
'./packages/vue-instantsearch'
'./packages/instantsearch.css'
'./packages/instantsearch-ui-components'
npx pkg-pr-new publish --compact --template './examples/js/getting-started' --template './examples/react/getting-started' --template './examples/react/next-app-router' --template './examples/react/next-routing' --template './examples/vue/getting-started' './packages/algoliasearch-helper' './packages/instantsearch.js' './packages/react-instantsearch' './packages/react-instantsearch-core' './packages/react-instantsearch-nextjs' './packages/react-instantsearch-router-nextjs' './packages/vue-instantsearch' './packages/instantsearch.css' './packages/instantsearch-ui-components'

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ scripts/*/CHANGELOG.md
.vscode/

# Caches
.eslintcache
.parcel-cache
.nuxt

Expand Down
Loading
Loading