mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-20 17:43:24 +00:00
Fix last accessibility issue in cookies modal and try CI to monitor regressions (#67)
* Add aria-label to cookies modal * Test lighthouse * Remove lighthouse as it doesn't work in bun https://github.com/oven-sh/bun/issues/4958 * Translate everything in search
This commit is contained in:
@@ -38,6 +38,7 @@ export function CookiesToast(props: { privacyPolicy?: string }) {
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label={tString(language, 'cookies_title')}
|
||||
aria-describedby={describedById}
|
||||
className={tcls(
|
||||
'fixed',
|
||||
|
||||
@@ -4,10 +4,12 @@ import Link from 'next/link';
|
||||
import React from 'react';
|
||||
|
||||
import { Loading } from '@/components/primitives';
|
||||
import { useLanguage } from '@/intl/client';
|
||||
import { t } from '@/intl/translate';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import { AskAnswerResult, askQuestion } from './server-actions';
|
||||
import { useSearch, useSearchLink } from './useSearch';
|
||||
import { useSearchLink } from './useSearch';
|
||||
|
||||
/**
|
||||
* Fetch and render the answers to a question.
|
||||
@@ -15,6 +17,8 @@ import { useSearch, useSearchLink } from './useSearch';
|
||||
export function SearchAskAnswer(props: { spaceId: string; query: string }) {
|
||||
const { spaceId, query } = props;
|
||||
|
||||
const language = useLanguage();
|
||||
|
||||
const [state, setState] = React.useState<
|
||||
| {
|
||||
type: 'answer';
|
||||
@@ -61,11 +65,11 @@ export function SearchAskAnswer(props: { spaceId: string; query: string }) {
|
||||
<AnswerBody answer={state.answer} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={tcls('p-4')}>No answer</div>
|
||||
<div className={tcls('p-4')}>{t(language, 'search_ask_no_answer')}</div>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
{state?.type === 'error' ? <div>Failed to fetch answer</div> : null}
|
||||
{state?.type === 'error' ? <div>{t(language, 'search_ask_error')}</div> : null}
|
||||
{!state ? (
|
||||
<div className={tcls('w-full', 'flex', 'items-center', 'justify-center')}>
|
||||
<Loading className={tcls('w-5', 'py-4', 'text-primary')} />
|
||||
@@ -78,10 +82,14 @@ export function SearchAskAnswer(props: { spaceId: string; query: string }) {
|
||||
function AnswerBody(props: { answer: AskAnswerResult }) {
|
||||
const { answer } = props;
|
||||
const getSearchLinkProps = useSearchLink();
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={tcls('mt-4', 'px-4', 'text-dark/9', 'dark:text-light/8')}>
|
||||
<div
|
||||
data-test="search-ask-answer"
|
||||
className={tcls('mt-4', 'px-4', 'text-dark/9', 'dark:text-light/8')}
|
||||
>
|
||||
{answer.body}
|
||||
</div>
|
||||
{answer.followupQuestions.length > 0 ? (
|
||||
@@ -135,7 +143,7 @@ function AnswerBody(props: { answer: AskAnswerResult }) {
|
||||
'dark:border-light/1',
|
||||
)}
|
||||
>
|
||||
<span className={tcls('text-sm')}>Sources</span>
|
||||
<span className={tcls('text-sm')}>{t(language, 'search_ask_sources')}</span>
|
||||
|
||||
{answer.sources.map((source) => (
|
||||
<span key={source.id} className={tcls()}>
|
||||
|
||||
@@ -60,6 +60,7 @@ export function SearchModal(props: SearchModalProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
role="dialog"
|
||||
className={tcls(
|
||||
'flex',
|
||||
'items-start',
|
||||
@@ -129,6 +130,7 @@ function SearchModalBody(
|
||||
return (
|
||||
<div
|
||||
role="dialog"
|
||||
aria-label={tString(language, 'search')}
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-col',
|
||||
@@ -173,6 +175,9 @@ function SearchModalBody(
|
||||
)}
|
||||
placeholder={tString(language, 'search_input_placeholder')}
|
||||
rows={1}
|
||||
spellCheck="false"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -163,6 +163,7 @@ export const SearchResults = React.forwardRef(function SearchResults(
|
||||
>
|
||||
{results.length === 0 ? (
|
||||
<div
|
||||
data-test="search-noresults"
|
||||
className={tcls(
|
||||
'text-sm',
|
||||
'text-dark',
|
||||
@@ -174,65 +175,67 @@ export const SearchResults = React.forwardRef(function SearchResults(
|
||||
{t(language, 'search_no_results', query)}
|
||||
</div>
|
||||
) : (
|
||||
results.map((item, index) => {
|
||||
switch (item.type) {
|
||||
case 'page': {
|
||||
return (
|
||||
<SearchPageResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
query={query}
|
||||
item={item}
|
||||
active={index === cursor}
|
||||
/>
|
||||
);
|
||||
<div data-test="search-results">
|
||||
{results.map((item, index) => {
|
||||
switch (item.type) {
|
||||
case 'page': {
|
||||
return (
|
||||
<SearchPageResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
query={query}
|
||||
item={item}
|
||||
active={index === cursor}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'question': {
|
||||
return (
|
||||
<SearchQuestionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
question={query}
|
||||
active={index === cursor}
|
||||
onClick={onSwitchToAsk}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'recommended-question': {
|
||||
return (
|
||||
<SearchQuestionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
question={item.question}
|
||||
active={index === cursor}
|
||||
onClick={onSwitchToAsk}
|
||||
recommended
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'section': {
|
||||
return (
|
||||
<SearchSectionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
query={query}
|
||||
item={item}
|
||||
active={index === cursor}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
assertNever(item);
|
||||
}
|
||||
case 'question': {
|
||||
return (
|
||||
<SearchQuestionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
question={query}
|
||||
active={index === cursor}
|
||||
onClick={onSwitchToAsk}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'recommended-question': {
|
||||
return (
|
||||
<SearchQuestionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
question={item.question}
|
||||
active={index === cursor}
|
||||
onClick={onSwitchToAsk}
|
||||
recommended
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'section': {
|
||||
return (
|
||||
<SearchSectionResultItem
|
||||
ref={(ref) => {
|
||||
refs.current[index] = ref;
|
||||
}}
|
||||
key={item.id}
|
||||
query={query}
|
||||
item={item}
|
||||
active={index === cursor}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
assertNever(item);
|
||||
}
|
||||
})
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
"search_input_placeholder": "Search content",
|
||||
"search_no_results": "No results for \"${1}\".",
|
||||
"search_ask": "Ask \"${1}\"",
|
||||
"search_ask_sources": "Sources",
|
||||
"search_ask_no_answer": "No answer could be found for your question, try with another one.",
|
||||
"search_ask_error": "Something went wrong. Please try again later.",
|
||||
"on_this_page": "On this page",
|
||||
"next_page": "Next",
|
||||
"previous_page": "Previous",
|
||||
@@ -19,6 +22,7 @@
|
||||
"code_copied": "Copied!",
|
||||
"code_copy": "Copy",
|
||||
"table_of_contents_button_label": "Open table of contents",
|
||||
"cookies_title": "Cookies",
|
||||
"cookies_prompt": "This site uses cookies to deliver its service and to analyse traffic. By browsing this site, you accept the ${1}.",
|
||||
"cookies_prompt_privacy": "privacy policy",
|
||||
"cookies_accept": "Accept",
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import puppeteer from 'puppeteer';
|
||||
import puppeteer, { Page } from 'puppeteer';
|
||||
import { argosScreenshot } from '@argos-ci/puppeteer';
|
||||
import { getContentTestURL, getTargetURL } from './utils';
|
||||
|
||||
interface Test {
|
||||
name: string;
|
||||
url: string;
|
||||
wait?: (page: Page) => Promise<any>;
|
||||
}
|
||||
|
||||
interface TestsCase {
|
||||
@@ -29,10 +30,12 @@ const testCases: TestsCase[] = [
|
||||
{
|
||||
name: 'Search Results',
|
||||
url: '?q=gitsync',
|
||||
wait: (page) => page.waitForSelector('[data-test="search-results"]'),
|
||||
},
|
||||
{
|
||||
name: 'AI Search',
|
||||
url: '?q=What+is+GitBook%3F&ask=1',
|
||||
wait: (page) => page.waitForSelector('[data-test="search-ask-answer"]'),
|
||||
},
|
||||
{
|
||||
name: 'Not found',
|
||||
|
||||
Reference in New Issue
Block a user