From 89002d5493787a466f4f13c5541d84e613c88fe9 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Mon, 28 Nov 2022 10:05:39 +0700 Subject: [PATCH 1/9] fix: enable schema description by default --- packages/graphiql/src/YogaGraphiQL.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphiql/src/YogaGraphiQL.tsx b/packages/graphiql/src/YogaGraphiQL.tsx index 5a4964dd2c..34ef4e5f6e 100644 --- a/packages/graphiql/src/YogaGraphiQL.tsx +++ b/packages/graphiql/src/YogaGraphiQL.tsx @@ -113,7 +113,6 @@ export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement { credentials: 'same-origin', specifiedByUrl: true, directiveIsRepeatable: true, - schemaDescription: true, ...props, headers: props.additionalHeaders || {}, }) @@ -152,6 +151,7 @@ export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement { Date: Mon, 28 Nov 2022 10:07:05 +0700 Subject: [PATCH 2/9] chore: correct graphiql default title in comment --- packages/graphql-yoga/src/plugins/useGraphiQL.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphql-yoga/src/plugins/useGraphiQL.ts b/packages/graphql-yoga/src/plugins/useGraphiQL.ts index 719821e742..40bb1e23f6 100644 --- a/packages/graphql-yoga/src/plugins/useGraphiQL.ts +++ b/packages/graphql-yoga/src/plugins/useGraphiQL.ts @@ -31,7 +31,7 @@ export type GraphiQLOptions = { */ headerEditorEnabled?: boolean /** - * The title to display at the top of the page. Defaults to `"YogaGraphiQL"`. + * The title to display at the top of the page. Defaults to `"Yoga GraphiQL"`. */ title?: string /** From 310d4ff2e6d2efd2f7947b823ed461005851c816 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Mon, 28 Nov 2022 10:38:56 +0700 Subject: [PATCH 3/9] chore: add changeset --- .changeset/nice-shirts-beam.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nice-shirts-beam.md diff --git a/.changeset/nice-shirts-beam.md b/.changeset/nice-shirts-beam.md new file mode 100644 index 0000000000..8b95351b14 --- /dev/null +++ b/.changeset/nice-shirts-beam.md @@ -0,0 +1,5 @@ +--- +'@graphql-yoga/graphiql': patch +--- + +fix enable graphiql schema description From 77002b590afe78c0a02c4067c762895204c8e871 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Mon, 28 Nov 2022 10:44:50 +0700 Subject: [PATCH 4/9] fix: enable graphiql default headers --- packages/graphiql/src/YogaGraphiQL.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/graphiql/src/YogaGraphiQL.tsx b/packages/graphiql/src/YogaGraphiQL.tsx index 34ef4e5f6e..09025df7f7 100644 --- a/packages/graphiql/src/YogaGraphiQL.tsx +++ b/packages/graphiql/src/YogaGraphiQL.tsx @@ -151,6 +151,7 @@ export function YogaGraphiQL(props: YogaGraphiQLProps): React.ReactElement { From da5d5a269d689ba079fea6e65de627fa3714f455 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Mon, 28 Nov 2022 11:00:47 +0700 Subject: [PATCH 5/9] chore: update docs --- packages/graphql-yoga/src/plugins/useGraphiQL.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/graphql-yoga/src/plugins/useGraphiQL.ts b/packages/graphql-yoga/src/plugins/useGraphiQL.ts index 40bb1e23f6..c592fafe55 100644 --- a/packages/graphql-yoga/src/plugins/useGraphiQL.ts +++ b/packages/graphql-yoga/src/plugins/useGraphiQL.ts @@ -20,6 +20,8 @@ export type GraphiQLOptions = { defaultVariableEditorOpen?: boolean /** * The initial headers to render inside the header editor. Defaults to `"{}"`. + * The value should be a JSON encoded string, for example: + * `headers: JSON.stringify({Authorization: "Bearer your-auth-key"})` */ headers?: string /** From e3ccec551a88c2cda05a75b871344a7205cc951d Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Mon, 28 Nov 2022 11:01:03 +0700 Subject: [PATCH 6/9] chore: update changeset --- .changeset/nice-shirts-beam.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/nice-shirts-beam.md b/.changeset/nice-shirts-beam.md index 8b95351b14..78b6f3f7a4 100644 --- a/.changeset/nice-shirts-beam.md +++ b/.changeset/nice-shirts-beam.md @@ -2,4 +2,4 @@ '@graphql-yoga/graphiql': patch --- -fix enable graphiql schema description +- fix: enable graphiql schema description, default headers prop From 666756db88b46e31fe04b4a713bd172a763e5d4b Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Tue, 29 Nov 2022 16:43:23 +0700 Subject: [PATCH 7/9] fix: remove unused graphiql options ref: https://github.com/graphql/graphiql/blob/main/docs/migration/graphiql-2.0.0.md --- packages/graphql-yoga/src/plugins/useGraphiQL.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/graphql-yoga/src/plugins/useGraphiQL.ts b/packages/graphql-yoga/src/plugins/useGraphiQL.ts index c592fafe55..f4f5f1ab3a 100644 --- a/packages/graphql-yoga/src/plugins/useGraphiQL.ts +++ b/packages/graphql-yoga/src/plugins/useGraphiQL.ts @@ -14,10 +14,6 @@ export type GraphiQLOptions = { * will use its own default query. */ defaultQuery?: string - /** - * Whether to open the variable editor by default. Defaults to `true`. - */ - defaultVariableEditorOpen?: boolean /** * The initial headers to render inside the header editor. Defaults to `"{}"`. * The value should be a JSON encoded string, for example: @@ -28,10 +24,6 @@ export type GraphiQLOptions = { * More info there: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials */ credentials?: RequestCredentials - /** - * Whether the header editor is enabled. Defaults to `true`. - */ - headerEditorEnabled?: boolean /** * The title to display at the top of the page. Defaults to `"Yoga GraphiQL"`. */ From 4f7370fbb78fbc79cfe81cafd3c85cd191976962 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Tue, 29 Nov 2022 16:55:29 +0700 Subject: [PATCH 8/9] test: add more integration tests for graphiql --- .../__integration-tests__/browser.spec.ts | 130 +++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/packages/graphql-yoga/__integration-tests__/browser.spec.ts b/packages/graphql-yoga/__integration-tests__/browser.spec.ts index 23670356a3..8227079498 100644 --- a/packages/graphql-yoga/__integration-tests__/browser.spec.ts +++ b/packages/graphql-yoga/__integration-tests__/browser.spec.ts @@ -2,7 +2,7 @@ import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store' import { GraphQLLiveDirective, useLiveQuery } from '@envelop/live-query' import { CORSOptions, createYoga, Repeater } from '../src/index.js' import { renderGraphiQL } from '@graphql-yoga/render-graphiql' -import puppeteer, { Browser, Page } from 'puppeteer' +import puppeteer, { Browser, ElementHandle, Page } from 'puppeteer' import { createServer, Server } from 'http' import { GraphQLObjectType, @@ -231,7 +231,62 @@ describe('browser', () => { return resultContents } + const showGraphiQLSidebar = async () => { + // Click to show sidebar + await page.click( + '.graphiql-sidebar [aria-label="Show Documentation Explorer"]', + ) + } + + const getElementText = async (element: ElementHandle) => + element.evaluate((el) => el.textContent?.trim()) + describe('GraphiQL', () => { + it('should show default title', async () => { + await page.goto(`http://localhost:${port}${endpoint}`) + + const title = await page.evaluate(() => document.title) + + expect(title).toBe('Yoga GraphiQL') + }) + + it('should show default schema docs', async () => { + await page.goto(`http://localhost:${port}${endpoint}`) + + // Click to show sidebar + await showGraphiQLSidebar() + + const docsElement = await page.waitForSelector( + '.graphiql-markdown-description', + ) + + expect(docsElement).not.toBeNull() + const docs = await getElementText(docsElement!) + + expect(docs).toBe( + 'A GraphQL schema provides a root type for each kind of operation.', + ) + }) + + it('should show editor tools by default', async () => { + await page.goto(`http://localhost:${port}${endpoint}`) + + // If this button is visible, that mean editor tools is showing + const buttonHideEditor = await page.$( + 'button[aria-label="Hide editor tools"]', + ) + + const editorTabs = await page.evaluate(() => + Array.from( + document.querySelectorAll('.graphiql-editor-tools-tabs button'), + (e) => e.textContent, + ), + ) + + expect(buttonHideEditor).not.toBeNull() + expect(editorTabs).toEqual(['Variables', 'Headers']) + }) + it('execute simple query operation', async () => { await page.goto(`http://localhost:${port}${endpoint}`) await typeOperationText('{ alwaysTrue }') @@ -437,6 +492,79 @@ describe('browser', () => { }) }) + describe('GraphiQL with custom options', () => { + let customGraphQLEndpoint: string + + const schemaWithDescription = createTestSchema() + schemaWithDescription.description = 'Here is the custom docs for schema' + + const defaultHeader = '{"Authorization":"Bearer test-auth-header"}' + const customServer = createServer( + createYoga({ + schema: schemaWithDescription, + logging: false, + graphqlEndpoint: endpoint, + graphiql: { + title: 'GraphiQL Custom title here', + headers: defaultHeader, + }, + renderGraphiQL, + }), + ) + + beforeAll(async () => { + await new Promise((resolve) => customServer.listen(0, resolve)) + const port = (customServer.address() as AddressInfo).port + customGraphQLEndpoint = `http://localhost:${port}${endpoint}` + }) + + afterAll(async () => { + await new Promise((resolve) => customServer.close(resolve)) + }) + + it('should show custom title', async () => { + await page.goto(customGraphQLEndpoint) + + const title = await page.evaluate(() => document.title) + + expect(title).toBe('GraphiQL Custom title here') + }) + + it('should show custom schema docs', async () => { + await page.goto(customGraphQLEndpoint) + + await showGraphiQLSidebar() + const docsElement = await page.waitForSelector( + '.graphiql-markdown-description', + ) + + expect(docsElement).not.toBeNull() + const docs = await getElementText(docsElement!) + + expect(docs).toBe(schemaWithDescription.description) + }) + + it('should include default header', async () => { + await page.goto(customGraphQLEndpoint) + + await page.evaluate(() => { + const tabs = Array.from( + document.querySelectorAll('.graphiql-editor-tools-tabs button'), + ) as HTMLButtonElement[] + tabs.find((tab) => tab.textContent === 'Headers')!.click() + }) + + const headerContentEl = await page.waitForSelector( + 'section.graphiql-editor-tool .graphiql-editor:not(.hidden) pre.CodeMirror-line', + ) + + expect(headerContentEl).not.toBeNull() + const headerContent = await getElementText(headerContentEl!) + + expect(headerContent).toBe(defaultHeader) + }) + }) + describe('CORS', () => { let anotherServer: Server let anotherOriginPort: number From f5cc2285a712ec940a168e02f78c19cc5c62b70f Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Tue, 29 Nov 2022 23:22:42 +0700 Subject: [PATCH 9/9] fix: deprecated instead of remove option --- packages/graphql-yoga/src/plugins/useGraphiQL.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/graphql-yoga/src/plugins/useGraphiQL.ts b/packages/graphql-yoga/src/plugins/useGraphiQL.ts index f4f5f1ab3a..fd3ea69032 100644 --- a/packages/graphql-yoga/src/plugins/useGraphiQL.ts +++ b/packages/graphql-yoga/src/plugins/useGraphiQL.ts @@ -14,6 +14,12 @@ export type GraphiQLOptions = { * will use its own default query. */ defaultQuery?: string + /** + * Whether to open the variable editor by default. Defaults to `true`. + * + * @deprecated Obsolete option. Variable editor was opened by default + */ + defaultVariableEditorOpen?: boolean /** * The initial headers to render inside the header editor. Defaults to `"{}"`. * The value should be a JSON encoded string, for example: @@ -24,6 +30,12 @@ export type GraphiQLOptions = { * More info there: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials */ credentials?: RequestCredentials + /** + * Whether the header editor is enabled. Defaults to `true`. + * + * @deprecated Obsolete option. Header editor was enabled by default + */ + headerEditorEnabled?: boolean /** * The title to display at the top of the page. Defaults to `"Yoga GraphiQL"`. */