chore(e2e): 👷 Fix e2e pipeline
This commit is contained in:
@ -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=
|
||||
|
19
.github/workflows/playwright.yml
vendored
19
.github/workflows/playwright.yml
vendored
@ -14,11 +14,24 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
- name: Run tests
|
||||
run: yarn turbo run test --scope=builder
|
||||
- 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
|
||||
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
|
||||
|
@ -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 {
|
||||
@ -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">
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
@ -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": "*",
|
||||
@ -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",
|
||||
@ -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",
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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[] = [
|
||||
@ -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
|
||||
},
|
||||
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
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
NextAuth(req, res, createOptions(req))
|
||||
NextAuth(req, res, {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
secret: process.env.SECRET,
|
||||
providers,
|
||||
session: {
|
||||
strategy: 'database',
|
||||
},
|
||||
callbacks: {
|
||||
session: async ({ session, user }) => ({ ...session, user }),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export default handler
|
||||
|
@ -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,
|
||||
@ -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: [
|
||||
|
5
apps/builder/playwright/.env.example
Normal file
5
apps/builder/playwright/.env.example
Normal file
@ -0,0 +1,5 @@
|
||||
PLAYWRIGHT_BUILDER_TEST_BASE_URL=http://localhost:3000
|
||||
|
||||
# For auth
|
||||
GITHUB_EMAIL=
|
||||
GITHUB_PASSWORD=
|
@ -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
|
||||
|
@ -5,20 +5,23 @@ import {
|
||||
Step,
|
||||
Typebot,
|
||||
} from 'models'
|
||||
import { CredentialsType, DashboardFolder, Plan, PrismaClient, User } from 'db'
|
||||
import { CredentialsType, DashboardFolder, PrismaClient, User } from 'db'
|
||||
import { readFileSync } from 'fs'
|
||||
|
||||
export const user = { id: 'user1', email: 'test1@gmail.com' }
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export const teardownDatabase = async () => prisma.user.deleteMany()
|
||||
|
||||
export const setupDatabase = async () => {
|
||||
await createUsers()
|
||||
export const setupDatabase = async (userEmail: string) => {
|
||||
const createdUser = await getSignedInUser(userEmail)
|
||||
if (!createdUser) throw new Error("Couldn't find user")
|
||||
process.env.PLAYWRIGHT_USER_ID = createdUser.id
|
||||
return createCredentials()
|
||||
}
|
||||
|
||||
const getSignedInUser = (email: string) =>
|
||||
prisma.user.findFirst({ where: { email } })
|
||||
|
||||
export const createTypebots = async (partialTypebots: Partial<Typebot>[]) => {
|
||||
await prisma.typebot.createMany({
|
||||
data: partialTypebots.map(parseTestTypebot) as any[],
|
||||
@ -33,47 +36,37 @@ export const createTypebots = async (partialTypebots: Partial<Typebot>[]) => {
|
||||
export const createFolders = (partialFolders: Partial<DashboardFolder>[]) =>
|
||||
prisma.dashboardFolder.createMany({
|
||||
data: partialFolders.map((folder) => ({
|
||||
ownerId: user.id,
|
||||
ownerId: process.env.PLAYWRIGHT_USER_ID as string,
|
||||
name: 'Folder #1',
|
||||
id: 'folder',
|
||||
...folder,
|
||||
})),
|
||||
})
|
||||
|
||||
const createUsers = () =>
|
||||
prisma.user.create({
|
||||
data: {
|
||||
...user,
|
||||
emailVerified: new Date(),
|
||||
plan: Plan.FREE,
|
||||
stripeId: 'stripe-test2',
|
||||
},
|
||||
})
|
||||
|
||||
const createCredentials = () => {
|
||||
if (!process.env.GOOGLE_REFRESH_TOKEN_TEST)
|
||||
console.warn(
|
||||
'GOOGLE_REFRESH_TOKEN_TEST env var is missing. It is required to run Google Sheets tests'
|
||||
)
|
||||
return prisma.credentials.createMany({
|
||||
const createCredentials = () =>
|
||||
prisma.credentials.createMany({
|
||||
data: [
|
||||
{
|
||||
name: 'test2@gmail.com',
|
||||
ownerId: user.id,
|
||||
ownerId: process.env.PLAYWRIGHT_USER_ID as string,
|
||||
type: CredentialsType.GOOGLE_SHEETS,
|
||||
data: {
|
||||
expiry_date: 1642441058842,
|
||||
access_token:
|
||||
'ya29.A0ARrdaM--PV_87ebjywDJpXKb77NBFJl16meVUapYdfNv6W6ZzqqC47fNaPaRjbDbOIIcp6f49cMaX5ndK9TAFnKwlVqz3nrK9nLKqgyDIhYsIq47smcAIZkK56SWPx3X3DwAFqRu2UPojpd2upWwo-3uJrod',
|
||||
refresh_token: process.env.GOOGLE_REFRESH_TOKEN_TEST,
|
||||
// This token is linked to a mock Google account (typebot.test.user@gmail.com)
|
||||
refresh_token:
|
||||
'1//03W5-TyIxXd7nCgYIARAAGAMSNwF-L9IrAGAmp5MG8RqVyk6YYmqDDn9x-4nHTkSUj4xZWuMs6mNeyjdS_bgO0CWuZEfJoAd_zIw',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUser = (data: Partial<User>) =>
|
||||
prisma.user.update({ data, where: { id: user.id } })
|
||||
prisma.user.update({
|
||||
data,
|
||||
where: { id: process.env.PLAYWRIGHT_USER_ID as string },
|
||||
})
|
||||
|
||||
export const createResults = async ({ typebotId }: { typebotId: string }) => {
|
||||
await prisma.result.createMany({
|
||||
@ -129,7 +122,7 @@ export const loadRawTypebotInDatabase = (typebot: Typebot) =>
|
||||
data: {
|
||||
...typebot,
|
||||
id: 'typebot4',
|
||||
ownerId: user.id,
|
||||
ownerId: process.env.PLAYWRIGHT_USER_ID,
|
||||
} as any,
|
||||
})
|
||||
|
||||
@ -137,7 +130,7 @@ const parseTestTypebot = (partialTypebot: Partial<Typebot>): Typebot => ({
|
||||
id: partialTypebot.id ?? 'typebot',
|
||||
folderId: null,
|
||||
name: 'My typebot',
|
||||
ownerId: user.id,
|
||||
ownerId: process.env.PLAYWRIGHT_USER_ID as string,
|
||||
theme: defaultTheme,
|
||||
settings: defaultSettings,
|
||||
createdAt: new Date(),
|
||||
@ -224,7 +217,13 @@ export const importTypebotInDatabase = (
|
||||
updates?: Partial<Typebot>
|
||||
) => {
|
||||
const typebot: Typebot = JSON.parse(readFileSync(path).toString())
|
||||
return prisma.typebot.create({
|
||||
data: { ...typebot, ...updates, ownerId: user.id } as any,
|
||||
})
|
||||
try {
|
||||
return prisma.typebot.create({
|
||||
data: {
|
||||
...typebot,
|
||||
...updates,
|
||||
ownerId: process.env.PLAYWRIGHT_USER_ID,
|
||||
} as any,
|
||||
})
|
||||
} catch {}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import test, { expect } from '@playwright/test'
|
||||
import { refreshUser } from '../services/browser'
|
||||
import { Plan } from 'db'
|
||||
import path from 'path'
|
||||
import { updateUser, user } from '../services/database'
|
||||
import { updateUser } from '../services/database'
|
||||
|
||||
test.describe('Account page', () => {
|
||||
test('should edit user info properly', async ({ page }) => {
|
||||
@ -14,17 +14,14 @@ test.describe('Account page', () => {
|
||||
).toBeDefined()
|
||||
await page.fill('#name', 'John Doe')
|
||||
expect(saveButton).toBeVisible()
|
||||
const avatarImg = page.locator('img')
|
||||
await expect(page.locator('text=JD')).toBeVisible()
|
||||
await expect(avatarImg).toBeHidden()
|
||||
await page.setInputFiles(
|
||||
'input[type="file"]',
|
||||
path.join(__dirname, '../fixtures/avatar.jpg')
|
||||
)
|
||||
await expect(avatarImg).toHaveAttribute(
|
||||
await expect(page.locator('img')).toHaveAttribute(
|
||||
'src',
|
||||
new RegExp(
|
||||
`https://s3.eu-west-3.amazonaws.com/typebot/users/${user.id}/avatar`,
|
||||
`https://s3.eu-west-3.amazonaws.com/typebot/users/${process.env.PLAYWRIGHT_USER_ID}/avatar`,
|
||||
'gm'
|
||||
)
|
||||
)
|
||||
@ -43,7 +40,6 @@ test.describe('Account page', () => {
|
||||
)
|
||||
await expect(manageSubscriptionButton).toBeHidden()
|
||||
await updateUser({ plan: Plan.PRO, stripeId: 'stripeId' })
|
||||
await page.evaluate(refreshUser)
|
||||
await page.reload()
|
||||
await expect(page.locator('text=Pro plan')).toBeVisible()
|
||||
await expect(manageSubscriptionButton).toBeVisible()
|
||||
|
@ -16,7 +16,10 @@ test.describe('Condition step', () => {
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/edit`)
|
||||
await page.click('text=Configure...')
|
||||
await page.fill('input[placeholder="Search for a variable"]', 'Age')
|
||||
await page.fill(
|
||||
'input[placeholder="Search for a variable"] >> nth=-1',
|
||||
'Age'
|
||||
)
|
||||
await page.click('button:has-text("Age")')
|
||||
await page.click('button:has-text("Select an operator")')
|
||||
await page.click('button:has-text("Greater than")', { force: true })
|
||||
@ -37,7 +40,10 @@ test.describe('Condition step', () => {
|
||||
)
|
||||
|
||||
await page.click('text=Configure...')
|
||||
await page.fill('input[placeholder="Search for a variable"]', 'Age')
|
||||
await page.fill(
|
||||
'input[placeholder="Search for a variable"] >> nth=-1',
|
||||
'Age'
|
||||
)
|
||||
await page.click('button:has-text("Age")')
|
||||
await page.click('button:has-text("Select an operator")')
|
||||
await page.click('button:has-text("Greater than")', { force: true })
|
||||
|
@ -6,7 +6,7 @@ import { importTypebotInDatabase } from '../../services/database'
|
||||
const typebotId = 'set-variable-step'
|
||||
|
||||
test.describe('Set variable step', () => {
|
||||
test('its configuration should work', async ({ page, context }) => {
|
||||
test('its configuration should work', async ({ page }) => {
|
||||
await importTypebotInDatabase(
|
||||
path.join(__dirname, '../../fixtures/typebots/logic/setVariable.json'),
|
||||
{
|
||||
@ -16,16 +16,19 @@ test.describe('Set variable step', () => {
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/edit`)
|
||||
await page.click('text=Type a number...')
|
||||
await page.fill('input[placeholder="Select a variable"]', 'Num')
|
||||
await page.fill('input[placeholder="Select a variable"] >> nth=-1', 'Num')
|
||||
await page.click('text=Create "Num"')
|
||||
|
||||
await page.click('text=Click to edit... >> nth = 0')
|
||||
await page.fill('input[placeholder="Select a variable"]', 'Total')
|
||||
await page.fill('input[placeholder="Select a variable"] >> nth=-1', 'Total')
|
||||
await page.click('text=Create "Total"')
|
||||
await page.fill('textarea', '1000 * {{Num}}')
|
||||
|
||||
await page.click('text=Click to edit...')
|
||||
await page.fill('input[placeholder="Select a variable"]', 'Custom var')
|
||||
await page.fill(
|
||||
'input[placeholder="Select a variable"] >> nth=-1',
|
||||
'Custom var'
|
||||
)
|
||||
await page.click('text=Create "Custom var"')
|
||||
await page.fill('textarea', 'Custom value')
|
||||
|
||||
|
@ -41,14 +41,18 @@ test.describe.parallel('Theme page', () => {
|
||||
test.describe('Chat', () => {
|
||||
test('should reflect change in real-time', async ({ page }) => {
|
||||
const typebotId = 'chat-theme-typebot'
|
||||
await importTypebotInDatabase(
|
||||
path.join(__dirname, '../fixtures/typebots/theme.json'),
|
||||
{
|
||||
id: typebotId,
|
||||
}
|
||||
)
|
||||
try {
|
||||
await importTypebotInDatabase(
|
||||
path.join(__dirname, '../fixtures/typebots/theme.json'),
|
||||
{
|
||||
id: typebotId,
|
||||
}
|
||||
)
|
||||
} catch {}
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/theme`)
|
||||
await page.click('button:has-text("Chat")')
|
||||
await page.waitForTimeout(300)
|
||||
|
||||
// Host bubbles
|
||||
await page.click(':nth-match([aria-label="Pick a color"], 1)')
|
||||
|
26
package.json
26
package.json
@ -11,34 +11,12 @@
|
||||
"db:nuke": "docker-compose down --volumes --remove-orphans",
|
||||
"dev": "dotenv -e .env yarn docker:up && dotenv -e .env turbo run dev --parallel",
|
||||
"build": "dotenv -e .env turbo run build",
|
||||
"test": "dotenv -e .env turbo run test",
|
||||
"test:builder": "cd apps/builder && yarn test",
|
||||
"lint": "turbo run lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dotenv-cli": "^4.1.1",
|
||||
"turbo": "^1.1.1"
|
||||
},
|
||||
"turbo": {
|
||||
"baseBranch": "origin/main",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".next/**"
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": [],
|
||||
"outputs": []
|
||||
},
|
||||
"lint": {
|
||||
"outputs": []
|
||||
},
|
||||
"dev": {
|
||||
"cache": false
|
||||
}
|
||||
}
|
||||
}
|
||||
"packageManager": "yarn@1.22.17"
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"models": "*",
|
||||
"qs": "^6.10.3",
|
||||
"react-frame-component": "5.2.2-alpha.0",
|
||||
"react-phone-number-input": "^3.1.44",
|
||||
"react-phone-number-input": "^3.1.45",
|
||||
"react-scroll": "^1.8.4",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"utils": "*"
|
||||
@ -25,19 +25,19 @@
|
||||
"@types/react-phone-number-input": "^3.0.13",
|
||||
"@types/react-scroll": "^1.8.3",
|
||||
"@types/react-transition-group": "^4.4.4",
|
||||
"autoprefixer": "^10.4.1",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.5",
|
||||
"rollup": "^2.63.0",
|
||||
"rollup": "^2.66.1",
|
||||
"rollup-plugin-dts": "^4.1.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"tailwindcss": "^3.0.11",
|
||||
"typescript": "^4.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.9.0",
|
||||
"tailwindcss": "^3.0.17",
|
||||
"typescript": "^4.5.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.1",
|
||||
"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"
|
||||
|
@ -6,10 +6,10 @@
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"typescript": "^4.5.4"
|
||||
"typescript": "^4.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^12.0.7",
|
||||
"next": "^12.0.9",
|
||||
"db": "*"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -10,14 +10,14 @@
|
||||
"@rollup/plugin-commonjs": "^21.0.1",
|
||||
"@rollup/plugin-node-resolve": "^13.1.3",
|
||||
"@rollup/plugin-typescript": "^8.3.0",
|
||||
"rollup": "^2.63.0",
|
||||
"rollup": "^2.66.1",
|
||||
"rollup-plugin-dts": "^4.1.0",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.4",
|
||||
"typescript": "^4.5.4"
|
||||
"typescript": "^4.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"models": "*",
|
||||
"next": "^12.0.7"
|
||||
"next": "^12.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn rollup -c",
|
||||
|
23
turbo.json
Normal file
23
turbo.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"baseBranch": "origin/main",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".next/**"
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": [],
|
||||
"outputs": []
|
||||
},
|
||||
"lint": {
|
||||
"outputs": []
|
||||
},
|
||||
"dev": {
|
||||
"cache": false
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user