Skip to content

Commit

Permalink
chore: add e2e tests for call and ingress requests (#3038)
Browse files Browse the repository at this point in the history
  • Loading branch information
wesbillman authored Oct 8, 2024
1 parent 7913488 commit 68d6ba3
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 36 deletions.
2 changes: 1 addition & 1 deletion backend/controller/ingress/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func manglePathParameters(params map[string]string, ref *schema.Ref, sch *schema
return map[string]any{}, nil
}

// Takes the map of path parameters and transforms them into the appropriate type
// Takes the map of query parameters and transforms them into the appropriate type
func mangleQueryParameters(params map[string]any, underlying map[string][]string, ref *schema.Ref, sch *schema.Schema) (any, error) {

paramsField, err := getField("query", ref, sch)
Expand Down
38 changes: 38 additions & 0 deletions frontend/console/e2e/echo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, ftlTest } from './ftl-test'
import { navigateToDecl } from './helpers'

ftlTest('shows echo verb form', async ({ page }) => {
await navigateToDecl(page, 'echo', 'echo')

await expect(page.getByText('CALL', { exact: true })).toBeVisible()
await expect(page.locator('input#request-path')).toHaveValue('echo.echo')

await expect(page.getByText('Body', { exact: true })).toBeVisible()
await expect(page.getByText('Verb Schema', { exact: true })).toBeVisible()
await expect(page.getByText('JSONSchema', { exact: true })).toBeVisible()
})

ftlTest('send echo request', async ({ page }) => {
await navigateToDecl(page, 'echo', 'echo')

// Check the initial value of the path input
const pathInput = page.locator('#request-path')
await expect(pathInput).toBeVisible()
const currentValue = await pathInput.inputValue()
expect(currentValue).toBe('echo.echo')

const bodyEditor = page.locator('#body-editor .cm-content[contenteditable="true"]')
await expect(bodyEditor).toBeVisible()
await bodyEditor.fill('{\n "name": "wicket"\n}')

await page.getByRole('button', { name: 'Send' }).click()

const responseEditor = page.locator('#response-editor .cm-content[role="textbox"]')
await expect(responseEditor).toBeVisible()

const responseText = await responseEditor.textContent()
const responseJson = JSON.parse(responseText.trim())

const expectedStart = 'Hello, wicket!!! It is '
expect(responseJson.message.startsWith(expectedStart)).toBe(true)
})
20 changes: 20 additions & 0 deletions frontend/console/e2e/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { type Page, expect } from '@playwright/test'

export async function navigateToModule(page: Page, moduleName: string) {
await page.getByRole('link', { name: 'Modules' }).click()

// Navigate to the module page
await page.locator(`#module-${moduleName}-view-icon`).click()
await expect(page).toHaveURL(new RegExp(`/modules/${moduleName}`))

// Expand the module tree group
await page.locator(`#module-${moduleName}-tree-group`).click()
}

export async function navigateToDecl(page: Page, moduleName: string, declName: string) {
await navigateToModule(page, moduleName)

// Navigate to the decl page
await page.locator(`div#decl-${declName}`).click()
await expect(page).toHaveURL(new RegExp(`/modules/${moduleName}/verb/${declName}`))
}
65 changes: 65 additions & 0 deletions frontend/console/e2e/ingress-http.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { expect, ftlTest } from './ftl-test'
import { navigateToDecl } from './helpers'

ftlTest('shows http ingress form', async ({ page }) => {
await navigateToDecl(page, 'http', 'get')

await expect(page.locator('#call-type')).toHaveText('GET')
await expect(page.locator('input#request-path')).toHaveValue('http://localhost:8891/get/name')

await expect(page.getByText('Body', { exact: true })).toBeVisible()
await expect(page.getByText('Verb Schema', { exact: true })).toBeVisible()
await expect(page.getByText('JSONSchema', { exact: true })).toBeVisible()
})

ftlTest('send get request with path and query params', async ({ page }) => {
await navigateToDecl(page, 'http', 'get')

// Check the initial value of the path input
const pathInput = page.locator('#request-path')
await expect(pathInput).toBeVisible()
const currentValue = await pathInput.inputValue()
expect(currentValue).toBe('http://localhost:8891/get/name')

// Update the path input to test path and query params
await pathInput.fill('http://localhost:8891/get/wicket?age=10')
await page.getByRole('button', { name: 'Send' }).click()

const responseEditor = page.locator('#response-editor .cm-content[role="textbox"]')
await expect(responseEditor).toBeVisible()

const responseText = await responseEditor.textContent()
const responseJson = JSON.parse(responseText)

expect(responseJson).toEqual({
age: '10',
name: 'wicket',
})
})

ftlTest('send post request with body', async ({ page }) => {
await navigateToDecl(page, 'http', 'post')

// Check the initial value of the path input
const pathInput = page.locator('#request-path')
await expect(pathInput).toBeVisible()
const currentValue = await pathInput.inputValue()
expect(currentValue).toBe('http://localhost:8891/post')

const bodyEditor = page.locator('#body-editor .cm-content[contenteditable="true"]')
await expect(bodyEditor).toBeVisible()
await bodyEditor.fill('{\n "age": 10,\n "name": "wicket"\n}')

await page.getByRole('button', { name: 'Send' }).click()

const responseEditor = page.locator('#response-editor .cm-content[role="textbox"]')
await expect(responseEditor).toBeVisible()

const responseText = await responseEditor.textContent()
const responseJson = JSON.parse(responseText)

expect(responseJson).toEqual({
age: 10,
name: 'wicket',
})
})
10 changes: 2 additions & 8 deletions frontend/console/e2e/module.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { expect, ftlTest } from './ftl-test'
import { navigateToModule } from './helpers'

ftlTest('shows verbs for deployment', async ({ page }) => {
const modulesNavItem = page.getByRole('link', { name: 'Modules' })
await modulesNavItem.click()

const moduleEchoRow = page.locator('div.cursor-pointer').getByText('echo')
const moduleEcho = moduleEchoRow.locator('svg').nth(1)
await moduleEcho.click()

await expect(page).toHaveURL(/\/modules\/echo/)
await navigateToModule(page, 'echo')

await expect(page.getByText('module echo {')).toBeVisible()
})
23 changes: 0 additions & 23 deletions frontend/console/e2e/verb.spec.ts

This file was deleted.

4 changes: 3 additions & 1 deletion frontend/console/src/components/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ export const CodeEditor = ({
onTextChanged,
readonly = false,
schema,
id,
}: {
value: string
onTextChanged?: (text: string) => void
readonly?: boolean
schema?: string
id?: string
}) => {
const { isDarkMode } = useUserPreferences()
const editorContainerRef = useRef(null)
Expand Down Expand Up @@ -111,5 +113,5 @@ export const CodeEditor = ({
}
}, [value])

return <div className='h-full' ref={editorContainerRef} />
return <div id={id} className='h-full' ref={editorContainerRef} />
}
2 changes: 2 additions & 0 deletions frontend/console/src/features/modules/ModulesTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const ModuleSection = ({
<li key={module.name} id={`module-tree-module-${module.name}`} className='mb-2'>
<div
ref={moduleRef}
id={`module-${module.name}-tree-group`}
className={classNames(
isSelected ? 'bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 hover:dark:bg-gray-600' : 'hover:bg-gray-200 hover:dark:bg-gray-700',
'group flex w-full modules-center gap-x-2 space-y-1 text-left text-sm font-medium cursor-pointer leading-6',
Expand All @@ -105,6 +106,7 @@ const ModuleSection = ({
<PackageIcon aria-hidden='true' className='size-4 my-1 ml-3 shrink-0' />
{module.name}
<CircleArrowRight02Icon
id={`module-${module.name}-view-icon`}
className='size-4 shrink-0 rounded-md hover:bg-gray-200 dark:hover:bg-gray-600'
onClick={(e) => {
e.preventDefault()
Expand Down
4 changes: 3 additions & 1 deletion frontend/console/src/features/verbs/VerbFormInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export const VerbFormInput = ({
return (
<form onSubmit={handleSubmit} className='rounded-lg'>
<div className='flex rounded-md shadow-sm'>
<span className='inline-flex items-center rounded-l-md border border-r-0 border-gray-300 dark:border-gray-500 px-3 ml-4 sm:text-sm'>{requestType}</span>
<span id='call-type' className='inline-flex items-center rounded-l-md border border-r-0 border-gray-300 dark:border-gray-500 px-3 ml-4 sm:text-sm'>
{requestType}
</span>
<input
type='text'
name='request-path'
Expand Down
4 changes: 2 additions & 2 deletions frontend/console/src/features/verbs/VerbRequestForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ export const VerbRequestForm = ({ module, verb }: { module?: Module; verb?: Verb
>
Reset
</button>
<CodeEditor value={bodyText} onTextChanged={handleBodyTextChanged} schema={schemaString} />
<CodeEditor id='body-editor' value={bodyText} onTextChanged={handleBodyTextChanged} schema={schemaString} />
</div>
}
bottomPanelContent={bottomText !== '' ? <CodeEditor value={bottomText} readonly onTextChanged={setHeadersText} /> : null}
bottomPanelContent={bottomText !== '' ? <CodeEditor id='response-editor' value={bottomText} readonly /> : null}
/>
)}
{activeTabId === 'verbschema' && <CodeEditor readonly value={verb?.schema ?? ''} />}
Expand Down

0 comments on commit 68d6ba3

Please sign in to comment.