Skip to content

Commit

Permalink
chore(e2e): 👷 Fix e2e pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Jan 28, 2022
1 parent 65209c2 commit 02bd2b9
Show file tree
Hide file tree
Showing 20 changed files with 958 additions and 902 deletions.
4 changes: 0 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,3 @@ STRIPE_WEBHOOK_SECRET=

# (Optional) Used for GIF search
NEXT_PUBLIC_GIPHY_API_KEY=

# (Optional) for e2e tests
PLAYWRIGHT_BUILDER_TEST_BASE_URL=http://localhost:3000
GOOGLE_REFRESH_TOKEN_TEST=
17 changes: 15 additions & 2 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,24 @@ jobs:
- uses: actions/checkout@v2
- name: Install dependencies
run: yarn
- name: Install Playwright
run: npx playwright install --with-deps
- name: Build db package
working-directory: ./packages/db
run: yarn build
env:
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- name: Build models package
working-directory: ./packages/models
run: yarn build
- name: Run tests
run: yarn turbo run test --scope=builder
working-directory: ./apps/builder
run: yarn test
env:
GOOGLE_REFRESH_TOKEN_TEST: ${{ secrets.GOOGLE_REFRESH_TOKEN_TEST }}
PLAYWRIGHT_BUILDER_TEST_BASE_URL: ${{ github.event.deployment_status.target_url }}
GITHUB_EMAIL: ${{ secrets.PLAYWRIGHT_GITHUB_EMAIL }}
GITHUB_PASSWORD: ${{ secrets.PLAYWRIGHT_GITHUB_PASSWORD }}
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v2
Expand Down
46 changes: 24 additions & 22 deletions apps/builder/components/account/PersonalInfoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { UploadIcon } from 'assets/icons'
import { UploadButton } from 'components/shared/buttons/UploadButton'
import { useUser } from 'contexts/UserContext'
import React, { ChangeEvent, useState } from 'react'
import { isDefined } from 'utils'

export const PersonalInfoForm = () => {
const {
Expand Down Expand Up @@ -75,28 +76,29 @@ export const PersonalInfoForm = () => {
onChange={handleNameChange}
/>
</FormControl>
<Tooltip
label="Can't update the email because it is linked to an OAuth service"
placement="left"
hasArrow
isDisabled={!isOAuthProvider}
>
<FormControl>
<FormLabel
htmlFor="email"
color={isOAuthProvider ? 'gray.500' : 'current'}
>
Email address
</FormLabel>
<Input
id="email"
type="email"
isDisabled={isOAuthProvider}
value={user?.email ?? ''}
onChange={handleEmailChange}
/>
</FormControl>
</Tooltip>
{isDefined(user?.email) && (
<Tooltip
label="Updating email is not available."
placement="left"
hasArrow
>
<FormControl>
<FormLabel
htmlFor="email"
color={isOAuthProvider ? 'gray.500' : 'current'}
>
Email address
</FormLabel>
<Input
id="email"
type="email"
isDisabled
value={user?.email ?? ''}
onChange={handleEmailChange}
/>
</FormControl>
</Tooltip>
)}

{hasUnsavedChanges && (
<Flex justifyContent="flex-end">
Expand Down
1 change: 1 addition & 0 deletions apps/builder/contexts/UserContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const UserContext = ({ children }: { children: ReactNode }) => {
if (status === 'loading') return
if (status === 'unauthenticated' && !isSigningIn())
router.replace('/signin')
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status, router])

const isSigningIn = () => ['/signin', '/register'].includes(router.pathname)
Expand Down
46 changes: 22 additions & 24 deletions apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "yarn playwright test",
"test:open": "PWDEBUG=1 yarn playwright test"
"test": "dotenv -e ./playwright/.env -- yarn playwright test",
"test:open": "dotenv -e ./playwright/.env -v PWDEBUG=1 -- yarn playwright test"
},
"dependencies": {
"@chakra-ui/css-reset": "^1.1.1",
"@chakra-ui/react": "^1.7.4",
"@chakra-ui/react": "^1.8.1",
"@codemirror/basic-setup": "^0.19.1",
"@codemirror/lang-css": "^0.19.3",
"@codemirror/lang-json": "^0.19.1",
Expand All @@ -23,14 +23,14 @@
"@giphy/js-types": "^4.1.0",
"@giphy/react-components": "^5.4.0",
"@googleapis/drive": "^2.1.0",
"@next-auth/prisma-adapter": "next",
"@udecode/plate-basic-marks": "^9.0.0",
"@next-auth/prisma-adapter": "1.0.1",
"@udecode/plate-basic-marks": "^9.2.1",
"@udecode/plate-common": "^7.0.2",
"@udecode/plate-core": "^9.0.0",
"@udecode/plate-link": "^9.0.0",
"@udecode/plate-ui-link": "^9.0.0",
"@udecode/plate-ui-toolbar": "^9.0.0",
"aws-sdk": "^2.1051.0",
"@udecode/plate-core": "^9.2.1",
"@udecode/plate-link": "^9.2.1",
"@udecode/plate-ui-link": "^9.2.1",
"@udecode/plate-ui-toolbar": "^9.2.1",
"aws-sdk": "^2.1065.0",
"bot-engine": "*",
"browser-image-compression": "^1.0.17",
"db": "*",
Expand All @@ -41,18 +41,18 @@
"google-spreadsheet": "^3.2.0",
"got": "^12.0.1",
"htmlparser2": "^7.2.0",
"immer": "^9.0.7",
"immer": "^9.0.12",
"js-video-url-parser": "^0.5.1",
"kbar": "^0.1.0-beta.24",
"micro": "^9.3.4",
"micro-cors": "^0.1.1",
"models": "*",
"next": "^12.0.7",
"next-auth": "beta",
"next": "^12.0.9",
"next-auth": "4.1.2",
"nodemailer": "^6.7.2",
"nprogress": "^0.2.0",
"papaparse": "^5.3.1",
"qs": "^6.10.2",
"qs": "^6.10.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-frame-component": "^5.2.1",
Expand All @@ -61,17 +61,17 @@
"slate": "^0.72.3",
"slate-history": "^0.66.0",
"slate-hyperscript": "^0.67.0",
"slate-react": "^0.72.1",
"stripe": "^8.195.0",
"slate-react": "^0.72.7",
"stripe": "^8.200.0",
"styled-components": "^5.3.3",
"svg-round-corners": "^0.3.0",
"swr": "^1.1.2",
"swr": "^1.2.0",
"use-debounce": "^7.0.1",
"use-immer": "^0.6.0",
"utils": "*"
},
"devDependencies": {
"@playwright/test": "^1.18.0",
"@playwright/test": "^1.18.1",
"@testing-library/cypress": "^8.0.2",
"@types/google-spreadsheet": "^3.1.5",
"@types/micro-cors": "^0.1.2",
Expand All @@ -82,17 +82,15 @@
"@types/react": "^17.0.38",
"@types/react-table": "^7.7.9",
"@types/testing-library__cypress": "^5.0.9",
"@typescript-eslint/eslint-plugin": "^5.9.0",
"cypress": "^9.2.0",
"cypress-file-upload": "^5.0.8",
"cypress-social-logins": "^1.13.0",
"@typescript-eslint/eslint-plugin": "^5.10.1",
"dotenv": "^14.3.2",
"eslint": "<8.0.0",
"eslint-config-next": "12.0.7",
"eslint-config-next": "12.0.9",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-prettier": "^4.0.0",
"next-transpile-modules": "^9.0.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4"
"typescript": "^4.5.5"
}
}
62 changes: 12 additions & 50 deletions apps/builder/pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import NextAuth, { NextAuthOptions } from 'next-auth'
import NextAuth from 'next-auth'
import { PrismaAdapter } from '@next-auth/prisma-adapter'
import EmailProvider from 'next-auth/providers/email'
import GitHubProvider from 'next-auth/providers/github'
import GoogleProvider from 'next-auth/providers/google'
import FacebookProvider from 'next-auth/providers/facebook'
import CredentialsProvider from 'next-auth/providers/credentials'
import prisma from 'libs/prisma'
import { Provider } from 'next-auth/providers'
import { User } from 'db'
import { NextApiRequest, NextApiResponse } from 'next'

const providers: Provider[] = [
Expand Down Expand Up @@ -48,54 +46,18 @@ if (process.env.FACEBOOK_CLIENT_ID && process.env.FACEBOOK_CLIENT_SECRET)
})
)

if (process.env.NODE_ENV !== 'production')
providers.push(
CredentialsProvider({
name: 'Credentials',
credentials: {
email: {
label: 'Email',
type: 'email',
placeholder: 'credentials@email.com',
},
},
async authorize(credentials) {
const user = await prisma.user.findUnique({
where: { email: credentials?.email },
})
return user
},
})
)

const createOptions = (req: NextApiRequest): NextAuthOptions => ({
adapter: PrismaAdapter(prisma),
secret: process.env.SECRET,
providers,
session: {
strategy: process.env.NODE_ENV === 'production' ? 'database' : 'jwt',
},
callbacks: {
jwt: async ({ token, user, account }) => {
if (req.url === '/api/auth/session?update' && token.user) {
token.user = await prisma.user.findUnique({
where: { id: (token.user as User).id },
})
} else if (user) {
token.user = user
}
account?.type && token && (token.providerType = account?.type)
return token
const handler = (req: NextApiRequest, res: NextApiResponse) => {
NextAuth(req, res, {
adapter: PrismaAdapter(prisma),
secret: process.env.SECRET,
providers,
session: {
strategy: 'database',
},
session: async ({ session, token, user }) => {
token?.user ? (session.user = token.user as User) : (session.user = user)
if (token?.providerType) session.providerType = token.providerType
return session
callbacks: {
session: async ({ session, user }) => ({ ...session, user }),
},
},
})

const handler = (req: NextApiRequest, res: NextApiResponse) => {
NextAuth(req, res, createOptions(req))
})
}

export default handler
3 changes: 2 additions & 1 deletion apps/builder/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const config: PlaywrightTestConfig = {
expect: {
timeout: 5000,
},
retries: process.env.CI ? 2 : 0,
retries: 2,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
maxFailures: process.env.CI ? 10 : undefined,
Expand All @@ -18,6 +18,7 @@ const config: PlaywrightTestConfig = {
trace: 'on-first-retry',
storageState: path.join(__dirname, 'playwright/authenticatedState.json'),
video: 'retain-on-failure',
locale: 'en-US',
},
outputDir: path.join(__dirname, 'playwright/test-results/'),
projects: [
Expand Down
5 changes: 5 additions & 0 deletions apps/builder/playwright/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PLAYWRIGHT_BUILDER_TEST_BASE_URL=http://localhost:3000

# For auth
GITHUB_EMAIL=
GITHUB_PASSWORD=
38 changes: 25 additions & 13 deletions apps/builder/playwright/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
import { chromium, FullConfig, Page } from '@playwright/test'
import { setupDatabase, teardownDatabase, user } from './services/database'
import { setupDatabase, teardownDatabase } from './services/database'

// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config({ path: '.env' })

async function globalSetup(config: FullConfig) {
const { baseURL } = config.projects[0].use
if (!baseURL) throw new Error('baseURL is missing')

await teardownDatabase()
await setupDatabase()

// Skip auth if debugging
if (process.env.PWDEBUG === '1') return

const browser = await chromium.launch()
const page = await browser.newPage()
await signIn(page, user.email)
await signIn(page)
await page.context().storageState({
path: './playwright/authenticatedState.json',
})

await setupDatabase(process.env.GITHUB_EMAIL as string)
}

const signIn = async (page: Page, email: string) => {
await page.goto('http://localhost:3000/api/auth/signin')
await page.fill('[placeholder="credentials\\@email\\.com"]', email)
await Promise.all([
page.waitForNavigation({ url: 'http://localhost:3000/typebots' }),
page.press('[placeholder="credentials\\@email\\.com"]', 'Enter'),
])
const signIn = async (page: Page) => {
if (!process.env.GITHUB_EMAIL || !process.env.GITHUB_PASSWORD)
throw new Error(
'GITHUB_USERNAME or GITHUB_PASSWORD are missing in the environment. They are required to log in.'
)
await page.goto(`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/signin`)
await page.click('text=Continue with GitHub')
await page.fill('input[name="login"]', process.env.GITHUB_EMAIL)
await page.fill('input[name="password"]', process.env.GITHUB_PASSWORD)
await page.press('input[name="password"]', 'Enter')
try {
await page.locator('text=Authorize baptisteArno').click({ timeout: 3000 })
} catch {
return
}
await page.waitForNavigation({
url: `${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/typebots`,
})
}

export default globalSetup
Loading

2 comments on commit 02bd2b9

@vercel
Copy link

@vercel vercel bot commented on 02bd2b9 Jan 28, 2022

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-git-main-typebot-io.vercel.app
builder-v2-typebot-io.vercel.app
next.typebot.io

@vercel
Copy link

@vercel vercel bot commented on 02bd2b9 Jan 28, 2022

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

typebot-io.vercel.app
viewer-v2-git-main-typebot-io.vercel.app
viewer-v2-typebot-io.vercel.app

Please sign in to comment.