chore: migrate to from yarn, lerna and shipjs to bun & changesets (#2827)
This commit is contained in:
parent
c94eafbbee
commit
0210db2f7d
48 changed files with 5881 additions and 28630 deletions
18
.changeset/README.md
Normal file
18
.changeset/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in the changesets repo](https://github.com/changesets/changesets).
|
||||
|
||||
## How to contribute a changeset
|
||||
|
||||
Before merging your PR, you should add a changeset if your change affects any of the published packages.
|
||||
|
||||
1. Run `bun run changeset` in the root of the repository
|
||||
2. Select the packages that are affected by your change
|
||||
3. Choose the type of version bump (major, minor, or patch)
|
||||
4. Write a summary of your changes that will be included in the changelog
|
||||
|
||||
All published `@docsearch/*` packages use a single version (fixed versioning). This means when one package is bumped, all packages get the same version.
|
||||
|
||||
## Releasing
|
||||
|
||||
When changesets are present in the `main` branch, the CI will create a "Version Packages" PR that bumps versions and updates changelogs. Merging that PR will trigger the publish workflow.
|
||||
26
.changeset/config.json
Normal file
26
.changeset/config.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"fixed": [
|
||||
[
|
||||
"@docsearch/css",
|
||||
"@docsearch/core",
|
||||
"@docsearch/js",
|
||||
"@docsearch/modal",
|
||||
"@docsearch/react",
|
||||
"@docsearch/sidepanel",
|
||||
"@docsearch/sidepanel-js",
|
||||
"@docsearch/docusaurus-adapter"
|
||||
]
|
||||
],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": [
|
||||
"@docsearch/website",
|
||||
"@docsearch/react-example",
|
||||
"@docsearch/js-example"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,21 +1,25 @@
|
|||
version: 2.1
|
||||
|
||||
aliases:
|
||||
- &restore_yarn_cache
|
||||
name: Restore Yarn cache
|
||||
- &install_bun
|
||||
name: Install Bun
|
||||
command: |
|
||||
npm install -g bun
|
||||
|
||||
- &restore_bun_cache
|
||||
name: Restore Bun cache
|
||||
keys:
|
||||
- yarn-packages-{{ checksum "yarn.lock" }}
|
||||
- bun-packages-{{ checksum "bun.lock" }}
|
||||
|
||||
- &save_yarn_cache
|
||||
name: Save Yarn cache
|
||||
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||
- &save_bun_cache
|
||||
name: Save Bun cache
|
||||
key: bun-packages-{{ checksum "bun.lock" }}
|
||||
paths:
|
||||
- .yarn/cache
|
||||
- .yarn/unplugged
|
||||
- ~/.bun/install/cache
|
||||
|
||||
- &run_yarn_install
|
||||
- &run_bun_install
|
||||
name: Install dependencies
|
||||
command: yarn install --immutable
|
||||
command: bun install --frozen-lockfile
|
||||
|
||||
- &restore_dist_folders
|
||||
name: Restore dist folders
|
||||
|
|
@ -29,6 +33,7 @@ aliases:
|
|||
mkdir -p packages/docsearch-modal/dist
|
||||
mkdir -p packages/docsearch-sidepanel/dist
|
||||
mkdir -p packages/docsearch-sidepanel-js/dist
|
||||
mkdir -p adapters/docusaurus-theme-search-algolia/lib
|
||||
|
||||
cp -R /tmp/workspace/packages/docsearch-react/dist packages/docsearch-react
|
||||
cp -R /tmp/workspace/packages/docsearch-js/dist packages/docsearch-js
|
||||
|
|
@ -37,16 +42,17 @@ aliases:
|
|||
cp -R /tmp/workspace/packages/docsearch-modal/dist packages/docsearch-modal
|
||||
cp -R /tmp/workspace/packages/docsearch-sidepanel/dist packages/docsearch-sidepanel
|
||||
cp -R /tmp/workspace/packages/docsearch-sidepanel-js/dist packages/docsearch-sidepanel-js
|
||||
cp -R /tmp/workspace/adapters/docusaurus-theme-search-algolia/lib adapters/docusaurus-theme-search-algolia
|
||||
|
||||
defaults: &defaults
|
||||
working_directory: ~/docsearch
|
||||
docker:
|
||||
- image: cimg/node:22.15.0
|
||||
|
||||
cypress: &cypress
|
||||
playwright: &playwright
|
||||
working_directory: ~/docsearch
|
||||
docker:
|
||||
- image: cypress/browsers:node-22.15.0-chrome-136.0.7103.113-1-ff-138.0.3-edge-136.0.3240.64-1
|
||||
- image: mcr.microsoft.com/playwright:v1.49.1-noble
|
||||
environment:
|
||||
## this enables colors in the output
|
||||
TERM: xterm
|
||||
|
|
@ -62,13 +68,14 @@ jobs:
|
|||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run:
|
||||
name: Build and Size
|
||||
command: |
|
||||
yarn run build
|
||||
bun run build
|
||||
- run:
|
||||
name: Move dist folders to workspace
|
||||
command: |
|
||||
|
|
@ -81,6 +88,7 @@ jobs:
|
|||
mkdir -p /tmp/workspace/packages/docsearch-modal/dist
|
||||
mkdir -p /tmp/workspace/packages/docsearch-sidepanel/dist
|
||||
mkdir -p /tmp/workspace/packages/docsearch-sidepanel-js/dist
|
||||
mkdir -p /tmp/workspace/adapters/docusaurus-theme-search-algolia/lib
|
||||
|
||||
cp -R packages/docsearch-react/dist /tmp/workspace/packages/docsearch-react
|
||||
cp -R packages/docsearch-js/dist /tmp/workspace/packages/docsearch-js
|
||||
|
|
@ -89,66 +97,73 @@ jobs:
|
|||
cp -R packages/docsearch-modal/dist /tmp/workspace/packages/docsearch-modal
|
||||
cp -R packages/docsearch-sidepanel/dist /tmp/workspace/packages/docsearch-sidepanel
|
||||
cp -R packages/docsearch-sidepanel-js/dist /tmp/workspace/packages/docsearch-sidepanel-js
|
||||
cp -R adapters/docusaurus-theme-search-algolia/lib /tmp/workspace/adapters/docusaurus-theme-search-algolia
|
||||
- persist_to_workspace:
|
||||
root: *workspace_root
|
||||
paths:
|
||||
- packages
|
||||
- adapters
|
||||
test_lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Linting
|
||||
command: yarn run lint
|
||||
command: bun run lint
|
||||
test_types:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Type checking
|
||||
command: yarn run test:types
|
||||
command: bun run test:types
|
||||
test_size:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Size checking
|
||||
command: yarn run test:size
|
||||
command: bun run test:size
|
||||
test_unit:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Unit tests
|
||||
command: yarn run test
|
||||
command: bun run test
|
||||
release:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Setup git user
|
||||
|
|
@ -157,19 +172,26 @@ jobs:
|
|||
git config --global user.name "algolia-bot"
|
||||
- run:
|
||||
name: Release if needed
|
||||
command: yarn run shipjs trigger
|
||||
test_cypress:
|
||||
<<: *cypress
|
||||
command: bun run release
|
||||
test_playwright:
|
||||
<<: *playwright
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- restore_cache: *restore_yarn_cache
|
||||
- run: *run_yarn_install
|
||||
- save_cache: *save_yarn_cache
|
||||
- run: *install_bun
|
||||
- restore_cache: *restore_bun_cache
|
||||
- run: *run_bun_install
|
||||
- save_cache: *save_bun_cache
|
||||
- run: *restore_dist_folders
|
||||
- run:
|
||||
name: Cypress test Actions
|
||||
command: yarn run cy:run
|
||||
name: Playwright E2E tests
|
||||
command: bun run pw:run
|
||||
- store_artifacts:
|
||||
path: playwright-report
|
||||
destination: playwright-report
|
||||
- store_artifacts:
|
||||
path: test-results
|
||||
destination: test-results
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
|
@ -188,7 +210,7 @@ workflows:
|
|||
- test_unit:
|
||||
requires:
|
||||
- build
|
||||
- test_cypress:
|
||||
- test_playwright:
|
||||
requires:
|
||||
- build
|
||||
- release:
|
||||
|
|
|
|||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -21,9 +21,9 @@ dist/
|
|||
# Environment files
|
||||
.env
|
||||
|
||||
# Cypress Video and Screenshots output
|
||||
cypress/screenshots/
|
||||
cypress/videos/
|
||||
# Playwright output
|
||||
playwright-report/
|
||||
test-results/
|
||||
|
||||
**/.yarn/*
|
||||
!**/.yarn/releases
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ node_modules
|
|||
dist
|
||||
build
|
||||
.cache
|
||||
adapters/docusaurus-theme-search-algolia/lib
|
||||
|
|
|
|||
934
.yarn/releases/yarn-4.6.0.cjs
vendored
934
.yarn/releases/yarn-4.6.0.cjs
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +0,0 @@
|
|||
nodeLinker: node-modules
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.6.0.cjs
|
||||
34
AGENTS.md
34
AGENTS.md
|
|
@ -4,7 +4,7 @@ This document provides guidelines for AI agents working on the DocSearch codebas
|
|||
|
||||
## Project Overview
|
||||
|
||||
DocSearch is an Algolia-powered search widget for documentation sites. It's a TypeScript/React monorepo using Yarn workspaces with Lerna for orchestration.
|
||||
DocSearch is an Algolia-powered search widget for documentation sites. It's a TypeScript/React monorepo using Bun workspaces.
|
||||
|
||||
### Packages
|
||||
|
||||
|
|
@ -21,62 +21,62 @@ DocSearch is an Algolia-powered search widget for documentation sites. It's a Ty
|
|||
|
||||
```bash
|
||||
# Install dependencies
|
||||
yarn install
|
||||
bun install
|
||||
|
||||
# Build all packages
|
||||
yarn build
|
||||
bun run build
|
||||
|
||||
# Build specific package
|
||||
yarn workspace @docsearch/react build
|
||||
bun --filter @docsearch/react build
|
||||
|
||||
# Watch mode (all packages)
|
||||
yarn watch
|
||||
bun run watch
|
||||
|
||||
# Clean builds
|
||||
yarn build:clean
|
||||
bun run build:clean
|
||||
```
|
||||
|
||||
## Test Commands
|
||||
|
||||
```bash
|
||||
# Run all unit tests
|
||||
yarn test
|
||||
bun run test
|
||||
|
||||
# Run a single test file
|
||||
yarn test packages/docsearch-react/src/__tests__/utils.test.ts
|
||||
bun run test packages/docsearch-react/src/__tests__/utils.test.ts
|
||||
|
||||
# Run tests matching a pattern
|
||||
yarn test --testNamePattern="extractLinksFromText"
|
||||
bun run test --testNamePattern="extractLinksFromText"
|
||||
|
||||
# Run tests in watch mode
|
||||
yarn test --watch
|
||||
bun run test --watch
|
||||
|
||||
# Type checking
|
||||
yarn test:types
|
||||
bun run test:types
|
||||
|
||||
# Bundle size check
|
||||
yarn test:size
|
||||
bun run test:size
|
||||
```
|
||||
|
||||
## Lint Commands
|
||||
|
||||
```bash
|
||||
# Run ESLint
|
||||
yarn lint
|
||||
bun run lint
|
||||
|
||||
# Run CSS linting
|
||||
yarn lint:css
|
||||
bun run lint:css
|
||||
```
|
||||
|
||||
## E2E Testing (Cypress)
|
||||
|
||||
```bash
|
||||
# Run Cypress tests
|
||||
yarn cy:run
|
||||
bun run cy:run
|
||||
|
||||
# Run with specific browser
|
||||
yarn cy:run:chrome
|
||||
yarn cy:run:firefox
|
||||
bun run cy:run:chrome
|
||||
bun run cy:run:firefox
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
|
|
|
|||
|
|
@ -60,12 +60,43 @@ Some examples of valid commit messages (used as first lines):
|
|||
To run this project, you will need:
|
||||
|
||||
- Node.js ≥ 18 – [nvm](https://github.com/nvm-sh/nvm#install-script) is recommended
|
||||
- [Yarn](https://yarnpkg.com)
|
||||
- [Bun](https://bun.sh) – our package manager and build tool
|
||||
|
||||
## Getting started
|
||||
|
||||
```sh
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Build all packages
|
||||
bun run build
|
||||
|
||||
# Run tests
|
||||
bun run test
|
||||
|
||||
# Start development mode (watch + playground)
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Changesets
|
||||
|
||||
This project uses [Changesets](https://github.com/changesets/changesets) for versioning and publishing.
|
||||
|
||||
If your PR includes changes that should be released, add a changeset:
|
||||
|
||||
```sh
|
||||
bun run changeset
|
||||
```
|
||||
|
||||
Select the packages affected by your change, choose the version bump type (major/minor/patch), and write a summary that will appear in the changelog.
|
||||
|
||||
## Release
|
||||
|
||||
```sh
|
||||
yarn run release
|
||||
```
|
||||
When changesets are merged to `main`, a "Version Packages" PR will be automatically created (or updated). Merging that PR triggers the release workflow:
|
||||
|
||||
It will create a pull request for the next release. When it's reviewed, approved and merged, then CircleCI will automatically publish it to npm.
|
||||
1. Package versions are bumped
|
||||
2. CHANGELOGs are updated
|
||||
3. Packages are published to npm
|
||||
4. Git tags are created
|
||||
|
||||
All `@docsearch/*` packages share the same version number (fixed versioning).
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ DocSearch crawls your documentation, pushes the content to an Algolia index and
|
|||
#### Installation
|
||||
|
||||
```sh
|
||||
yarn add @docsearch/js@4
|
||||
bun add @docsearch/js@4
|
||||
# or
|
||||
npm install @docsearch/js@4
|
||||
```
|
||||
|
|
@ -74,7 +74,7 @@ docsearch({
|
|||
#### Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/react@4
|
||||
bun add @docsearch/react@4
|
||||
# or
|
||||
npm install @docsearch/react@4
|
||||
```
|
||||
|
|
|
|||
|
|
@ -27,14 +27,15 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "yarn exec tsc --build --force && node ./scripts/copy-assets.mjs && node ./scripts/format-theme.mjs",
|
||||
"build:clean": "yarn clean && yarn build",
|
||||
"build": "bun x tsc --build --force && node ./scripts/copy-assets.mjs && node ./scripts/format-theme.mjs",
|
||||
"build:clean": "bun run clean && bun run build",
|
||||
"clean": "rm -rf lib tsconfig.*.tsbuildinfo",
|
||||
"watch": "run-p -c copy:watch build:watch",
|
||||
"build:watch": "yarn exec tsc --build --watch",
|
||||
"build:watch": "bun x tsc --build --watch",
|
||||
"copy:watch": "node ./scripts/copy-assets.mjs --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-core": "1.19.2",
|
||||
"@docsearch/react": "4.6.0",
|
||||
"@docusaurus/core": "^3.9.2",
|
||||
"@docusaurus/plugin-content-docs": "^3.9.2",
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
"@docusaurus/core": "^3.9.2",
|
||||
"@docusaurus/module-type-aliases": "3.9.2",
|
||||
"@docusaurus/theme-classic": "3.9.2",
|
||||
"@docusaurus/types": "^3.9.2",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/lodash": "^4.17.10",
|
||||
"glob": "^13.0.6",
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
projectId: 'nf9rdc',
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:3000',
|
||||
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||
},
|
||||
});
|
||||
Binary file not shown.
|
|
@ -1,48 +0,0 @@
|
|||
/// <reference path="../support/commands.d.ts" />
|
||||
|
||||
describe.skip('Ask AI', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(Cypress.config().baseUrl!);
|
||||
cy.openModal();
|
||||
});
|
||||
|
||||
it('Results are displayed after a query', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Hits').should('be.visible');
|
||||
});
|
||||
|
||||
it('Shows Ask AI as a hit on search', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-AskAi-Section').should('be.visible');
|
||||
});
|
||||
|
||||
it('Opens Ask AI on enter key', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Input').type('{enter}');
|
||||
cy.get('.DocSearch-AskAiScreen').should('be.visible');
|
||||
});
|
||||
|
||||
it('Opens Ask AI on click', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('#docsearch-askAI-item-0').click();
|
||||
cy.get('.DocSearch-AskAiScreen').should('be.visible');
|
||||
});
|
||||
|
||||
it('Streams response after query', () => {
|
||||
cy.goToAskAi();
|
||||
cy.get('.DocSearch-AskAiScreen-Query').should('be.visible');
|
||||
cy.get('.DocSearch-AskAiScreen-Message').should('be.visible');
|
||||
});
|
||||
|
||||
it('Copy button copies the response to the clipboard', () => {
|
||||
cy.goToAskAi();
|
||||
cy.get('.DocSearch-AskAiScreen-Response').should('be.visible');
|
||||
cy.window().its('navigator.permissions').invoke('query', { name: 'clipboard-read' }).its('state').then(cy.log);
|
||||
cy.window()
|
||||
.its('navigator.clipboard')
|
||||
.invoke('readText')
|
||||
.then((text) => {
|
||||
expect(text.length).to.be.greaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
/// <reference path="../support/commands.d.ts" />
|
||||
|
||||
describe('Start', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(Cypress.config().baseUrl!);
|
||||
cy.waitLoad();
|
||||
});
|
||||
|
||||
it('Open modal on search button click', () => {
|
||||
cy.openModal();
|
||||
cy.modalIsVisibleAndFocused();
|
||||
|
||||
// check that the scrollbar offset is compensated
|
||||
cy.get('body').should('have.css', 'overflow', 'hidden');
|
||||
cy.get('.DocSearch-Modal').should('be.visible');
|
||||
});
|
||||
|
||||
it('Open modal with key shortcut on Windows/Linux', () => {
|
||||
cy.get('body').type('{ctrl}k');
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
|
||||
it('Open modal with key shortcut on Windows/Linux when caps lock is on', () => {
|
||||
cy.get('body').type('{ctrl}K');
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
|
||||
it('Open modal with key shortcut on macOS', () => {
|
||||
cy.get('body').type('{meta}k');
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
|
||||
it('Open modal with key shortcut on macOS when caps lock is on', () => {
|
||||
cy.get('body').type('{meta}K');
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
|
||||
it('Open modal with forward slash key shortcut', () => {
|
||||
cy.get('body').wait(1000).type('/');
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
});
|
||||
|
||||
describe('End', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(Cypress.config().baseUrl!);
|
||||
cy.openModal();
|
||||
});
|
||||
|
||||
it('Close modal with Esc key', () => {
|
||||
cy.closeModal();
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
|
||||
it('Close modal by clicking outside its container', () => {
|
||||
cy.get('body').click(0, 0);
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
|
||||
it('Close modal with key shortcut on Windows/Linux', () => {
|
||||
cy.get('body').type('{ctrl}k');
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
|
||||
it('Close modal with key shortcut on macOS', () => {
|
||||
cy.get('body').type('{meta}k');
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Search', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(Cypress.config().baseUrl!);
|
||||
cy.openModal();
|
||||
});
|
||||
|
||||
it('Results are displayed after a query', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Hits').should('be.visible');
|
||||
});
|
||||
|
||||
it('Query can be cleared', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Clear').click();
|
||||
cy.get('.DocSearch-Hits').should('not.exist');
|
||||
});
|
||||
|
||||
it('Keyboard navigation leads to result', () => {
|
||||
const currentURL = cy.url();
|
||||
|
||||
cy.typeQueryMatching();
|
||||
cy.get('.DocSearch-Input').type('{downArrow}{downArrow}{upArrow}');
|
||||
cy.get('.DocSearch-Input').type('{enter}');
|
||||
cy.on('url:changed', (newUrl) => {
|
||||
expect(newUrl).not.equal(currentURL);
|
||||
});
|
||||
});
|
||||
|
||||
it('Pointer navigation leads to result', () => {
|
||||
const currentURL = cy.url();
|
||||
|
||||
cy.typeQueryMatching();
|
||||
cy.get('#docsearch-hits_docsearch_0-item-1 > a').click({
|
||||
force: true,
|
||||
});
|
||||
cy.on('url:changed', (newUrl) => {
|
||||
expect(newUrl).not.equal(currentURL);
|
||||
});
|
||||
});
|
||||
|
||||
it("No results are displayed if query doesn't match", () => {
|
||||
cy.typeQueryNotMatching();
|
||||
cy.contains('No results found for').should('be.visible');
|
||||
});
|
||||
|
||||
it('Should not refer to Recent/Favorite in aria-controls', () => {
|
||||
cy.get('.DocSearch-Input').should('not.have.attr', 'aria-controls');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Recent and Favorites', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(Cypress.config().baseUrl!);
|
||||
cy.openModal();
|
||||
cy.typeQueryMatching();
|
||||
cy.get('#docsearch-hits_docsearch_0-item-1 > a').click({ force: true }).wait(1000);
|
||||
cy.openModal();
|
||||
cy.contains('Recent').should('be.visible');
|
||||
});
|
||||
|
||||
it('Recent search is displayed after visiting a result', () => {
|
||||
cy.clearSearch();
|
||||
cy.get('#docsearch-recentSearches-item-0').should('be.visible');
|
||||
});
|
||||
|
||||
it('Recent search can be deleted', () => {
|
||||
cy.get('#docsearch-recentSearches-item-0').find('[title="Remove this search from history"]').trigger('click');
|
||||
cy.get('.DocSearch-Hits').should('not.exist');
|
||||
});
|
||||
|
||||
it('Recent search can be favorited', () => {
|
||||
cy.get('#docsearch-recentSearches-item-0').find('[title="Save this search"]').trigger('click');
|
||||
cy.contains('Favorite').should('be.visible');
|
||||
cy.get('#docsearch-favoriteSearches-item-0').should('be.visible');
|
||||
});
|
||||
|
||||
it('Favorite can be deleted', () => {
|
||||
cy.get('#docsearch-recentSearches-item-0').find('[title="Save this search"]').trigger('click');
|
||||
cy.contains('Favorite').should('be.visible');
|
||||
cy.get('#docsearch-favoriteSearches-item-0').find('[title="Remove this search from favorites"]').trigger('click');
|
||||
cy.get('.DocSearch-Hits').should('not.exist');
|
||||
});
|
||||
});
|
||||
55
cypress/support/commands.d.ts
vendored
55
cypress/support/commands.d.ts
vendored
|
|
@ -1,55 +0,0 @@
|
|||
/// <reference types="cypress" />
|
||||
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
/**
|
||||
* Ensures the modal is visible and focused.
|
||||
*/
|
||||
modalIsVisibleAndFocused: () => void;
|
||||
/**
|
||||
* Ensures the modal not visible.
|
||||
*/
|
||||
modalIsNotVisible: () => void;
|
||||
/**
|
||||
* Toggles the dark mode on the preview website.
|
||||
*/
|
||||
darkmode: () => void;
|
||||
/**
|
||||
* Wait for the page to load.
|
||||
*/
|
||||
waitLoad: () => void;
|
||||
/**
|
||||
* Opens the DocSearch modal.
|
||||
*/
|
||||
openModal: () => void;
|
||||
/**
|
||||
* Closes the DocSearch modal.
|
||||
*/
|
||||
closeModal: () => void;
|
||||
/**
|
||||
* Search for a given query.
|
||||
*/
|
||||
search: (query: string) => void;
|
||||
/**
|
||||
* Types a query that returns results.
|
||||
*/
|
||||
typeQueryMatching: () => void;
|
||||
|
||||
/**
|
||||
* Clears the search input.
|
||||
*/
|
||||
clearSearch: () => void;
|
||||
/**
|
||||
* Types a query that returns no results.
|
||||
*/
|
||||
typeQueryNotMatching: () => void;
|
||||
/**
|
||||
* Returns to the keyword search screen.
|
||||
*/
|
||||
returnToSearch: () => void;
|
||||
/**
|
||||
* Navigates to the Ask AI screen.
|
||||
*/
|
||||
goToAskAi: () => void;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
Cypress.Commands.add('modalIsVisibleAndFocused', () => {
|
||||
cy.get('.DocSearch-Modal', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('.DocSearch-Input').should('be.focus');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('modalIsNotVisible', () => {
|
||||
cy.get('body').should('not.have.class', 'DocSearch--active');
|
||||
cy.get('.DocSearch-Modal').should('not.exist');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('darkmode', () => {
|
||||
cy.get('.react-toggle').click({ force: true });
|
||||
cy.get('.react-toggle-screenreader-only').blur();
|
||||
cy.get('html.dark').should('be.visible');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('waitLoad', () => {
|
||||
cy.get('.DocSearch-Button', { timeout: 10000 }).should('be.visible');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('openModal', () => {
|
||||
cy.get('.DocSearch-Button').should('be.visible').click();
|
||||
cy.modalIsVisibleAndFocused();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('closeModal', () => {
|
||||
cy.get('body').type('{esc}');
|
||||
cy.modalIsNotVisible();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('search', (query: string) => {
|
||||
cy.get('.DocSearch-Input').should('be.visible').type(query);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('typeQueryMatching', () => {
|
||||
cy.search('g');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('typeQueryNotMatching', () => {
|
||||
cy.search('zzz');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('clearSearch', () => {
|
||||
cy.get('.DocSearch-Input').clear();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('returnToSearch', () => {
|
||||
cy.get('.DocSearch-Input').type('{esc}');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('goToAskAi', () => {
|
||||
cy.typeQueryMatching();
|
||||
cy.get('#docsearch-AskAi-Section').click();
|
||||
});
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["cypress"]
|
||||
},
|
||||
"exclude": []
|
||||
}
|
||||
47
e2e/askai.spec.ts
Normal file
47
e2e/askai.spec.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { test, expect } from './fixtures';
|
||||
|
||||
test.describe.skip('Ask AI', () => {
|
||||
test.beforeEach(async ({ docSearch }) => {
|
||||
await docSearch.goto();
|
||||
await docSearch.openModal();
|
||||
});
|
||||
|
||||
test('Results are displayed after a query', async ({ docSearch }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await expect(docSearch.hits).toBeVisible();
|
||||
});
|
||||
|
||||
test('Shows Ask AI as a hit on search', async ({ docSearch, page }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await expect(page.locator('.DocSearch-AskAi-Section')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Opens Ask AI on enter key', async ({ docSearch, page }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await page.keyboard.press('Enter');
|
||||
await expect(page.locator('.DocSearch-AskAiScreen')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Opens Ask AI on click', async ({ docSearch, page }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await page.locator('#docsearch-askAI-item-0').click();
|
||||
await expect(page.locator('.DocSearch-AskAiScreen')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Streams response after query', async ({ docSearch, page }) => {
|
||||
await docSearch.goToAskAi();
|
||||
await expect(page.locator('.DocSearch-AskAiScreen-Query')).toBeVisible();
|
||||
await expect(page.locator('.DocSearch-AskAiScreen-Message')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Copy button copies the response to the clipboard', async ({ docSearch, page, context }) => {
|
||||
// Grant clipboard permissions
|
||||
await context.grantPermissions(['clipboard-read', 'clipboard-write']);
|
||||
|
||||
await docSearch.goToAskAi();
|
||||
await expect(page.locator('.DocSearch-AskAiScreen-Response')).toBeVisible();
|
||||
|
||||
const clipboardText = await page.evaluate(() => navigator.clipboard.readText());
|
||||
expect(clipboardText.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
84
e2e/fixtures.ts
Normal file
84
e2e/fixtures.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import { test as base, expect, type Page, type Locator } from '@playwright/test';
|
||||
|
||||
export class DocSearchPage {
|
||||
readonly page: Page;
|
||||
readonly searchButton: Locator;
|
||||
readonly modal: Locator;
|
||||
readonly input: Locator;
|
||||
readonly hits: Locator;
|
||||
readonly clearButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.searchButton = page.locator('.DocSearch-Button');
|
||||
this.modal = page.locator('.DocSearch-Modal');
|
||||
this.input = page.locator('.DocSearch-Input');
|
||||
this.hits = page.locator('.DocSearch-Hits').first();
|
||||
this.clearButton = page.locator('.DocSearch-Clear');
|
||||
}
|
||||
|
||||
async goto(): Promise<void> {
|
||||
await this.page.goto('/');
|
||||
}
|
||||
|
||||
async waitForLoad(): Promise<void> {
|
||||
await expect(this.searchButton).toBeVisible({ timeout: 10000 });
|
||||
}
|
||||
|
||||
async openModal(): Promise<void> {
|
||||
await this.searchButton.click();
|
||||
await this.expectModalVisibleAndFocused();
|
||||
}
|
||||
|
||||
async closeModal(): Promise<void> {
|
||||
await this.page.keyboard.press('Escape');
|
||||
await this.expectModalNotVisible();
|
||||
}
|
||||
|
||||
async expectModalVisibleAndFocused(): Promise<void> {
|
||||
await expect(this.modal).toBeVisible({ timeout: 10000 });
|
||||
await expect(this.input).toBeFocused();
|
||||
}
|
||||
|
||||
async expectModalNotVisible(): Promise<void> {
|
||||
await expect(this.page.locator('body')).not.toHaveClass(/DocSearch--active/);
|
||||
await expect(this.modal).not.toBeVisible();
|
||||
}
|
||||
|
||||
async search(query: string): Promise<void> {
|
||||
await this.input.fill(query);
|
||||
}
|
||||
|
||||
async typeQueryMatching(): Promise<void> {
|
||||
await this.search('g');
|
||||
}
|
||||
|
||||
async typeQueryNotMatching(): Promise<void> {
|
||||
await this.search('zzz');
|
||||
}
|
||||
|
||||
async clearSearch(): Promise<void> {
|
||||
await this.input.clear();
|
||||
}
|
||||
|
||||
async enableDarkMode(): Promise<void> {
|
||||
await this.page.locator('.react-toggle').click({ force: true });
|
||||
await this.page.locator('.react-toggle-screenreader-only').blur();
|
||||
await expect(this.page.locator('html.dark')).toBeVisible();
|
||||
}
|
||||
|
||||
async goToAskAi(): Promise<void> {
|
||||
await this.typeQueryMatching();
|
||||
await this.page.locator('#docsearch-AskAi-Section').click();
|
||||
}
|
||||
}
|
||||
|
||||
export const test = base.extend<{ docSearch: DocSearchPage }>({
|
||||
docSearch: async ({ page }, use) => {
|
||||
const docSearch = new DocSearchPage(page);
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
await use(docSearch);
|
||||
},
|
||||
});
|
||||
|
||||
export { expect };
|
||||
155
e2e/search.spec.ts
Normal file
155
e2e/search.spec.ts
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import { test, expect } from './fixtures';
|
||||
|
||||
test.describe('Start', () => {
|
||||
test.beforeEach(async ({ docSearch }) => {
|
||||
await docSearch.goto();
|
||||
await docSearch.waitForLoad();
|
||||
});
|
||||
|
||||
test('Open modal on search button click', async ({ docSearch, page }) => {
|
||||
await docSearch.openModal();
|
||||
|
||||
// check that the scrollbar offset is compensated
|
||||
await expect(page.locator('body')).toHaveCSS('overflow', 'hidden');
|
||||
await expect(docSearch.modal).toBeVisible();
|
||||
});
|
||||
|
||||
test('Open modal with key shortcut on Windows/Linux', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Control+k');
|
||||
await docSearch.expectModalVisibleAndFocused();
|
||||
});
|
||||
|
||||
test('Open modal with key shortcut on Windows/Linux when caps lock is on', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Control+K');
|
||||
await docSearch.expectModalVisibleAndFocused();
|
||||
});
|
||||
|
||||
test('Open modal with key shortcut on macOS', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Meta+k');
|
||||
await docSearch.expectModalVisibleAndFocused();
|
||||
});
|
||||
|
||||
test('Open modal with key shortcut on macOS when caps lock is on', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Meta+K');
|
||||
await docSearch.expectModalVisibleAndFocused();
|
||||
});
|
||||
|
||||
test('Open modal with forward slash key shortcut', async ({ docSearch, page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.keyboard.press('/');
|
||||
await docSearch.expectModalVisibleAndFocused();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('End', () => {
|
||||
test.beforeEach(async ({ docSearch }) => {
|
||||
await docSearch.goto();
|
||||
await docSearch.openModal();
|
||||
});
|
||||
|
||||
test('Close modal with Esc key', async ({ docSearch }) => {
|
||||
await docSearch.closeModal();
|
||||
});
|
||||
|
||||
test('Close modal by clicking outside its container', async ({ docSearch, page }) => {
|
||||
await page.mouse.click(0, 0);
|
||||
await docSearch.expectModalNotVisible();
|
||||
});
|
||||
|
||||
test('Close modal with key shortcut on Windows/Linux', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Control+k');
|
||||
await docSearch.expectModalNotVisible();
|
||||
});
|
||||
|
||||
test('Close modal with key shortcut on macOS', async ({ docSearch, page }) => {
|
||||
await page.keyboard.press('Meta+k');
|
||||
await docSearch.expectModalNotVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Search', () => {
|
||||
test.beforeEach(async ({ docSearch }) => {
|
||||
await docSearch.goto();
|
||||
await docSearch.openModal();
|
||||
});
|
||||
|
||||
test('Results are displayed after a query', async ({ docSearch }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await expect(docSearch.hits).toBeVisible();
|
||||
});
|
||||
|
||||
test('Query can be cleared', async ({ docSearch }) => {
|
||||
await docSearch.typeQueryMatching();
|
||||
await docSearch.clearButton.click();
|
||||
await expect(docSearch.hits).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Keyboard navigation leads to result', async ({ docSearch, page }) => {
|
||||
const initialURL = page.url();
|
||||
|
||||
await docSearch.typeQueryMatching();
|
||||
await expect(docSearch.hits).toBeVisible();
|
||||
await page.keyboard.press('ArrowDown');
|
||||
await page.keyboard.press('ArrowDown');
|
||||
await page.keyboard.press('ArrowUp');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
await expect(page).not.toHaveURL(initialURL, { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('Pointer navigation leads to result', async ({ docSearch, page }) => {
|
||||
const initialURL = page.url();
|
||||
|
||||
await docSearch.typeQueryMatching();
|
||||
await page.locator('#docsearch-hits_docsearch_0-item-1 > a').click({ force: true });
|
||||
|
||||
await expect(page).not.toHaveURL(initialURL);
|
||||
});
|
||||
|
||||
test("No results are displayed if query doesn't match", async ({ docSearch, page }) => {
|
||||
await docSearch.typeQueryNotMatching();
|
||||
await expect(page.getByText('No results found for')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Should not refer to Recent/Favorite in aria-controls', async ({ docSearch }) => {
|
||||
await expect(docSearch.input).not.toHaveAttribute('aria-controls');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Recent and Favorites', () => {
|
||||
test.beforeEach(async ({ docSearch, page }) => {
|
||||
await docSearch.goto();
|
||||
await docSearch.openModal();
|
||||
await docSearch.typeQueryMatching();
|
||||
await page.locator('#docsearch-hits_docsearch_0-item-1 > a').click({ force: true });
|
||||
await page.waitForTimeout(1000);
|
||||
await docSearch.openModal();
|
||||
await expect(page.getByText('Recent')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Recent search is displayed after visiting a result', async ({ docSearch, page }) => {
|
||||
await docSearch.clearSearch();
|
||||
await expect(page.locator('#docsearch-recentSearches-item-0')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Recent search can be deleted', async ({ docSearch, page }) => {
|
||||
await page.locator('#docsearch-recentSearches-item-0').locator('[title="Remove this search from history"]').click();
|
||||
await expect(docSearch.hits).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Recent search can be favorited', async ({ page }) => {
|
||||
await page.locator('#docsearch-recentSearches-item-0').locator('[title="Save this search"]').click();
|
||||
await expect(page.getByText('Favorite')).toBeVisible();
|
||||
await expect(page.locator('#docsearch-favoriteSearches-item-0')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Favorite can be deleted', async ({ docSearch, page }) => {
|
||||
await page.locator('#docsearch-recentSearches-item-0').locator('[title="Save this search"]').click();
|
||||
await expect(page.getByText('Favorite')).toBeVisible();
|
||||
await page
|
||||
.locator('#docsearch-favoriteSearches-item-0')
|
||||
.locator('[title="Remove this search from favorites"]')
|
||||
.click();
|
||||
await expect(docSearch.hits).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import algolia from 'eslint-config-algolia/flat/base.js';
|
||||
import algoliaReact from 'eslint-config-algolia/flat/react.js';
|
||||
import algoliaTypescript from 'eslint-config-algolia/flat/typescript.js';
|
||||
import cypresss from 'eslint-plugin-cypress/flat'; // eslint-disable-line import/no-unresolved
|
||||
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||
import tseslint from 'typescript-eslint'; // eslint-disable-line import/no-unresolved
|
||||
|
||||
|
|
@ -10,7 +9,16 @@ export default [
|
|||
...algoliaReact,
|
||||
...algoliaTypescript,
|
||||
{
|
||||
ignores: ['**/node_modules/', '**/dist/', '**/build/', '.yarn/', '**/.docusaurus'],
|
||||
ignores: [
|
||||
'**/node_modules/',
|
||||
'**/dist/',
|
||||
'**/build/',
|
||||
'.yarn/',
|
||||
'**/.docusaurus',
|
||||
'scratchpad/**',
|
||||
'adapters/**/lib/**',
|
||||
'**/rollup.config-*.cjs',
|
||||
],
|
||||
},
|
||||
{
|
||||
plugins: {
|
||||
|
|
@ -74,12 +82,9 @@ export default [
|
|||
},
|
||||
tseslint.configs.disableTypeChecked,
|
||||
{
|
||||
files: ['cypress/**/*'],
|
||||
plugins: {
|
||||
cypresss,
|
||||
},
|
||||
files: ['e2e/**/*'],
|
||||
rules: {
|
||||
'@typescript-eslint/triple-slash-reference': 0,
|
||||
'@typescript-eslint/no-floating-promises': 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"packages": [
|
||||
"adapters/*",
|
||||
"packages/*",
|
||||
"examples/*"
|
||||
],
|
||||
"version": "4.6.0",
|
||||
"npmClient": "yarn"
|
||||
}
|
||||
63
package.json
63
package.json
|
|
@ -7,32 +7,49 @@
|
|||
"examples/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "lerna run build",
|
||||
"cy:clean": "rm -rf cypress/screenshots",
|
||||
"cy:info": "cypress info",
|
||||
"cy:run:chrome": "yarn run cy:run --browser chrome",
|
||||
"cy:run:edge": "yarn run cy:run --browser edge",
|
||||
"cy:run:firefox": "yarn run cy:run --browser firefox",
|
||||
"cy:run": "start-server-and-test 'yarn workspace @docsearch/docusaurus-adapter build && yarn website:test' http://localhost:3000 'cypress run --headless'",
|
||||
"cy:verify": "cypress verify",
|
||||
"build": "bun run --sequential build:stage:base build:stage:react build:stage:consumers build:stage:adapter website:build",
|
||||
"build:all": "bun run --sequential build website:build",
|
||||
"build:pkg:core": "bun --filter @docsearch/core build",
|
||||
"build:pkg:css": "bun --filter @docsearch/css build",
|
||||
"build:pkg:react": "bun --filter @docsearch/react build",
|
||||
"build:pkg:js": "bun --filter @docsearch/js build",
|
||||
"build:pkg:sidepanel": "bun --filter @docsearch/sidepanel build",
|
||||
"build:pkg:sidepanel-js": "bun --filter @docsearch/sidepanel-js build",
|
||||
"build:pkg:modal": "bun --filter @docsearch/modal build",
|
||||
"build:pkg:adapter": "bun --filter @docsearch/docusaurus-adapter build",
|
||||
"build:stage:base": "bun run --parallel build:pkg:core build:pkg:css",
|
||||
"build:stage:react": "bun run build:pkg:react",
|
||||
"build:stage:consumers": "bun run --parallel build:pkg:js build:pkg:sidepanel build:pkg:sidepanel-js build:pkg:modal",
|
||||
"build:stage:adapter": "bun run build:pkg:adapter",
|
||||
"build:examples": "bun --filter './examples/*' build",
|
||||
"pw:clean": "rm -rf playwright-report test-results",
|
||||
"pw:run": "start-server-and-test 'bun run website:test' http://localhost:3000 'playwright test'",
|
||||
"pw:run:chromium": "bun run pw:run -- --project=chromium",
|
||||
"pw:run:firefox": "bun run pw:run -- --project=firefox",
|
||||
"pw:run:webkit": "bun run pw:run -- --project=webkit",
|
||||
"pw:ui": "start-server-and-test 'bun run website:test' http://localhost:3000 'playwright test --ui'",
|
||||
"lint:css": "stylelint **/src/**/*.css",
|
||||
"lint": "eslint .",
|
||||
"playground:build": "yarn workspace @docsearch/react-example build",
|
||||
"playground:start": "yarn workspace @docsearch/react-example dev --host",
|
||||
"playground-js:start": "yarn workspace @docsearch/js-example dev --host",
|
||||
"release": "shipjs prepare",
|
||||
"start": "yarn run watch",
|
||||
"dev": "yarn start & yarn playground:start",
|
||||
"playground:build": "bun --filter @docsearch/react-example build",
|
||||
"playground:start": "bun --filter @docsearch/react-example dev -- --host",
|
||||
"playground-js:start": "bun --filter @docsearch/js-example dev -- --host",
|
||||
"start": "bun run watch",
|
||||
"dev": "bun run start & bun run playground:start",
|
||||
"test:size": "bundlesize",
|
||||
"test:types": "tsc --noEmit",
|
||||
"test": "vitest",
|
||||
"watch": "lerna run watch --parallel",
|
||||
"website:build": "yarn workspace @docsearch/website build",
|
||||
"website:start": "yarn workspace @docsearch/website start --host 0.0.0.0",
|
||||
"website:serve": "yarn workspace @docsearch/website serve --host 0.0.0.0",
|
||||
"website:test": "yarn workspace @docsearch/website start --no-open"
|
||||
"watch": "bun --filter './packages/*' watch",
|
||||
"website:build": "bun --filter @docsearch/website build",
|
||||
"website:start": "bun --filter @docsearch/website start -- --host 0.0.0.0",
|
||||
"website:serve": "bun --filter @docsearch/website serve -- --host 0.0.0.0",
|
||||
"website:test": "bun --filter @docsearch/website start -- --no-open",
|
||||
"changeset": "changeset",
|
||||
"version": "changeset version && bun run sync:docsearch-version",
|
||||
"release": "changeset publish",
|
||||
"sync:docsearch-version": "bun scripts/updateDocsearchVersion.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.29.7",
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
|
||||
"@stylistic/eslint-plugin": "2.13.0",
|
||||
"@testing-library/dom": "10.4.0",
|
||||
|
|
@ -42,11 +59,10 @@
|
|||
"@typescript-eslint/parser": "8.20.0",
|
||||
"bundlesize2": "0.0.32",
|
||||
"cssnano": "7.0.6",
|
||||
"cypress": "13.17.0",
|
||||
"@playwright/test": "1.49.1",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-config-algolia": "23.2.1",
|
||||
"eslint-config-prettier": "10.0.1",
|
||||
"eslint-plugin-cypress": "4.1.0",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-jsdoc": "50.6.2",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
|
|
@ -55,13 +71,11 @@
|
|||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-react-refresh": "0.4.18",
|
||||
"jsdom": "26.0.0",
|
||||
"lerna": "8.1.9",
|
||||
"postcss": "8.5.1",
|
||||
"prettier": "3.4.2",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"rolldown": "1.0.0-beta.57",
|
||||
"shipjs": "0.27.0",
|
||||
"start-server-and-test": "2.0.10",
|
||||
"stylelint": "16.13.2",
|
||||
"stylelint-config-sass-guidelines": "12.1.0",
|
||||
|
|
@ -73,6 +87,5 @@
|
|||
"typescript-eslint": "8.20.0",
|
||||
"vitest": "3.0.2",
|
||||
"watch": "1.0.2"
|
||||
},
|
||||
"packageManager": "yarn@4.6.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "6.6.3",
|
||||
"@testing-library/react": "16.2.0",
|
||||
"preact": "11.0.0-beta.0",
|
||||
"tsdown": "^0.18.3",
|
||||
"typescript": "5.7.3",
|
||||
"vitest": "3.0.2"
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ Style package for [DocSearch](http://docsearch.algolia.com/), the best search ex
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/css@4
|
||||
# or
|
||||
npm install @docsearch/css@4
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
"scripts": {
|
||||
"build:clean": "rm -rf ./dist",
|
||||
"build:css": "node build-css.js",
|
||||
"build": "yarn build:clean && mkdir dist && yarn build:css",
|
||||
"watch": "nodemon --watch 'src/**/*.css' --exec 'yarn build:css' --ext css"
|
||||
"build": "bun run build:clean && mkdir dist && bun run build:css",
|
||||
"watch": "nodemon --watch 'src/**/*.css' --exec 'bun run build:css' --ext css"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.1.9"
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ JavaScript package for [DocSearch](http://docsearch.algolia.com/), the best sear
|
|||
## Installation
|
||||
|
||||
```sh
|
||||
yarn add @docsearch/js@4
|
||||
# or
|
||||
npm install @docsearch/js@4
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"devDependencies": {
|
||||
"@docsearch/react": "4.6.0",
|
||||
"htm": "3.1.1",
|
||||
"preact": "^10.0.0",
|
||||
"preact": "11.0.0-beta.0",
|
||||
"tsdown": "^0.18.3",
|
||||
"typescript": "5.7.3"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@
|
|||
"@docsearch/react": "4.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docsearch/core": "4.5.3",
|
||||
"@docsearch/react": "4.5.3",
|
||||
"@testing-library/jest-dom": "6.6.3",
|
||||
"@testing-library/react": "16.2.0",
|
||||
"tsdown": "^0.18.3",
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ React package for [DocSearch](http://docsearch.algolia.com/), the best search ex
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/react@4
|
||||
# or
|
||||
npm install @docsearch/react@4
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
"ai": "^5.0.30",
|
||||
"algoliasearch": "^5.28.0",
|
||||
"marked": "^16.3.0",
|
||||
"preact": "11.0.0-beta.0",
|
||||
"tsdown": "^0.18.3",
|
||||
"typescript": "5.7.3",
|
||||
"vitest": "3.0.2",
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ JavaScript package for [DocSearch Sidepanel](http://docsearch.algolia.com/), a s
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/sidepanel-js
|
||||
# or
|
||||
npm install @docsearch/sidepanel-js
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@docsearch/react": "4.6.0",
|
||||
"preact": "^11.0.0-beta.0",
|
||||
"preact": "11.0.0-beta.0",
|
||||
"tsdown": "^0.18.3",
|
||||
"typescript": "5.7.3"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ React package for [DocSearch Sidepanel](http://docsearch.algolia.com/), a standa
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/core@4 @docsearch/sidepanel@4 @docsearch/css@4
|
||||
# or
|
||||
npm install @docsearch/core@4 @docsearch/sidepanel@4 @docsearch/css@4
|
||||
```
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@
|
|||
"@docsearch/react": "4.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docsearch/core": "4.5.3",
|
||||
"@docsearch/react": "4.5.3",
|
||||
"@testing-library/jest-dom": "6.6.3",
|
||||
"@testing-library/react": "16.2.0",
|
||||
"tsdown": "^0.18.3",
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ Check out our [website][2] for a complete explanation and documentation.
|
|||
|
||||
# Installation
|
||||
|
||||
1. In the root of this repository (two level above this directory), do `yarn install` and `yarn build`
|
||||
1. In this directory, do `yarn start`.
|
||||
1. In the root of this repository (two levels above this directory), do `bun install` and `bun run build`
|
||||
1. In this directory, do `bun run start`.
|
||||
1. A browser window will open up, pointing to the docs.
|
||||
|
||||
# Deployment
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ If your docs site is powered by Docusaurus, use [`@docsearch/docusaurus-adapter`
|
|||
<TabItem value="js">
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/js@4
|
||||
# or with npm
|
||||
npm install @docsearch/js@4
|
||||
```
|
||||
|
||||
|
|
@ -53,7 +51,7 @@ And the JavaScript at the end of your `<body>`:
|
|||
<TabItem value="react">
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/react@4
|
||||
bun add @docsearch/react@4
|
||||
# or
|
||||
npm install @docsearch/react@4
|
||||
```
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ This package is a dependency of [`@docsearch/js`][1] and [`@docsearch/react`][1]
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add @docsearch/css@4
|
||||
# or
|
||||
npm install @docsearch/css@4
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
"@docsearch/core": "workspace:*",
|
||||
"@docsearch/css": "workspace:*",
|
||||
"@docsearch/docusaurus-adapter": "workspace:*",
|
||||
"@docsearch/modal": "workspace:*",
|
||||
"@docsearch/react": "workspace:*",
|
||||
"@docsearch/sidepanel": "workspace:*",
|
||||
"@docusaurus/core": "3.9.2",
|
||||
"@docusaurus/preset-classic": "3.9.2",
|
||||
"@docusaurus/theme-common": "3.9.2",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@tabler/icons-react": "^3.34.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
|
|
|||
28
playwright.config.ts
Normal file
28
playwright.config.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
fullyParallel: true,
|
||||
forbidOnly: Boolean(process.env.CI),
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: process.env.CI ? 'html' : 'list',
|
||||
use: {
|
||||
baseURL: 'http://localhost:3000',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
/* {
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
}, */
|
||||
],
|
||||
});
|
||||
25
scripts/updateDocsearchVersion.ts
Normal file
25
scripts/updateDocsearchVersion.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const root = process.cwd();
|
||||
const packageJsonPath = join(root, 'packages', 'docsearch-react', 'package.json');
|
||||
const versionFilePath = join(root, 'packages', 'docsearch-react', 'src', 'version.ts');
|
||||
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
||||
const packageVersion = packageJson.version;
|
||||
|
||||
if (typeof packageVersion !== 'string') {
|
||||
throw new Error('Unable to determine @docsearch/react version.');
|
||||
}
|
||||
|
||||
const nextContent = `export const version = '${packageVersion}';\n`;
|
||||
const currentContent = readFileSync(versionFilePath, 'utf8');
|
||||
|
||||
if (currentContent === nextContent) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.info('DocSearch version file already up to date.');
|
||||
} else {
|
||||
writeFileSync(versionFilePath, nextContent, 'utf8');
|
||||
// eslint-disable-next-line no-console
|
||||
console.info(`Updated docsearch-react version to ${packageVersion}.`);
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const packages = [
|
||||
'adapters/docusaurus-theme-search-algolia',
|
||||
'packages/docsearch-css',
|
||||
'packages/docsearch-react',
|
||||
'packages/docsearch-js',
|
||||
'packages/docsearch-core',
|
||||
'packages/docsearch-modal',
|
||||
'packages/docsearch-sidepanel',
|
||||
'packages/docsearch-sidepanel-js',
|
||||
];
|
||||
|
||||
export default {
|
||||
monorepo: {
|
||||
mainVersionFile: 'lerna.json',
|
||||
// We rely on Lerna to bump our dependencies.
|
||||
packagesToBump: [],
|
||||
packagesToPublish: packages,
|
||||
},
|
||||
publishCommand({ tag }) {
|
||||
return `npm publish --tag ${tag} --access public`;
|
||||
},
|
||||
versionUpdated({ exec, dir, version }) {
|
||||
// Update package dependencies
|
||||
exec(`yarn lerna version ${version} --exact --no-git-tag-version --no-push --yes`);
|
||||
|
||||
// Ship.js reads JSON and writes with `fs.writeFileSync(JSON.stringify(json, null, 2))`
|
||||
// which causes a lint error in the `lerna.json` file.
|
||||
exec('yarn eslint lerna.json --fix');
|
||||
|
||||
fs.writeFileSync(
|
||||
path.resolve(dir, 'packages', 'docsearch-react', 'src', 'version.ts'),
|
||||
`export const version = '${version}';\n`,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
"**/__mocks__/**/*",
|
||||
"**/dist",
|
||||
"**/node_modules",
|
||||
"cypress",
|
||||
"e2e",
|
||||
"examples"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ export default defineConfig({
|
|||
test: {
|
||||
environment: 'jsdom',
|
||||
setupFiles: ['./scripts/setupTests.ts'],
|
||||
include: ['packages/**/src/**/*.test.ts', 'tests/**/*.test.ts'],
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue