diff --git a/.github/workflows/run-e2e.yml b/.github/workflows/run-e2e.yml new file mode 100644 index 0000000..cfb5b71 --- /dev/null +++ b/.github/workflows/run-e2e.yml @@ -0,0 +1,68 @@ +name: E2E Tests + +on: [push, pull_request] + +jobs: + cypress-run: + runs-on: ubuntu-latest + + steps: + # 1️⃣ Faz o checkout do código + - name: Checkout repository + uses: actions/checkout@v4 + + # 2️⃣ Instala o pnpm + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + run_install: false + + # 3️⃣ Instala Node.js com cache do pnpm + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'pnpm' + + # 4️⃣ Instala dependências + - name: Install dependencies + run: pnpm install + + # 5️⃣ Cache do binário do Cypress + - name: Cache Cypress binary + uses: actions/cache@v4 + with: + path: ~/.cache/Cypress + key: cypress-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }} + + # 6️⃣ Instala binário do Cypress + - name: Install Cypress binary + run: pnpm cypress install + + # 7️⃣ Build do projeto — agora com as variáveis definidas + - name: Build project + run: pnpm build + env: + NODE_ENV: production + APP_URL: 'http://localhost:3000' + NEXT_PUBLIC_API_BASE_URL: 'https://devstore-api-lilac.vercel.app/' + + # 8️⃣ Inicia o servidor em segundo plano + - name: Start Next.js server + run: pnpm start & + env: + NODE_ENV: production + APP_URL: 'http://localhost:3000' + NEXT_PUBLIC_API_BASE_URL: 'https://devstore-api-lilac.vercel.app/' + + # 9️⃣ Aguarda o servidor estar disponível + - name: Wait for server to be ready + run: npx wait-on http://localhost:3000 + + # 🔟 Executa os testes E2E + - name: Run Cypress tests + run: pnpm cypress run + env: + APP_URL: 'http://localhost:3000' + NEXT_PUBLIC_API_BASE_URL: 'https://devstore-api-lilac.vercel.app/' diff --git a/cypress/e2e/add-to-product-to-cart.cy.ts b/cypress/e2e/add-to-product-to-cart.cy.ts index 0f9dd44..7c9c73d 100644 --- a/cypress/e2e/add-to-product-to-cart.cy.ts +++ b/cypress/e2e/add-to-product-to-cart.cy.ts @@ -18,7 +18,7 @@ describe('add product to cart', () => { cy.contains('Cart(1)').should('exist') }) it('should be able to search for a product and add it to the cart', () => { - cy.searchByQuery('moletom') + cy.get('input[name="q"]').type('moletom').parent('form').submit() cy.get('a[href^="/product"]').first().click() cy.location('pathname').should('include', '/product') cy.contains('Adicionar ao carrinho').click() diff --git a/cypress/e2e/search.cy.ts b/cypress/e2e/search.cy.ts index c24d62f..009c392 100644 --- a/cypress/e2e/search.cy.ts +++ b/cypress/e2e/search.cy.ts @@ -1,7 +1,7 @@ describe('search products', () => { it('should be able to search for products ', () => { cy.visit('/') - cy.searchByQuery('moletom') + cy.get('input[name="q"]').type('moletom').parent('form').submit() cy.location('pathname').should('include', '/search') cy.location('search').should('include', 'q=moletom') cy.get('a[href^="/product"]', { timeout: 10000 }).should('exist') diff --git a/package.json b/package.json index 38814d8..4ee4c2f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "eslint" }, "dependencies": { + "@t3-oss/env-nextjs": "^0.13.8", "lucide-react": "^0.548.0", "next": "16.0.0", "react": "19.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 199125d..4f30f6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@t3-oss/env-nextjs': + specifier: ^0.13.8 + version: 0.13.8(typescript@5.9.3)(zod@4.1.12) lucide-react: specifier: ^0.548.0 version: 0.548.0(react@19.2.0) @@ -422,6 +425,40 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@t3-oss/env-core@0.13.8': + resolution: {integrity: sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw==} + peerDependencies: + arktype: ^2.1.0 + typescript: '>=5.0.0' + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0-beta.0 + peerDependenciesMeta: + arktype: + optional: true + typescript: + optional: true + valibot: + optional: true + zod: + optional: true + + '@t3-oss/env-nextjs@0.13.8': + resolution: {integrity: sha512-QmTLnsdQJ8BiQad2W2nvV6oUpH4oMZMqnFEjhVpzU0h3sI9hn8zb8crjWJ1Amq453mGZs6A4v4ihIeBFDOrLeQ==} + peerDependencies: + arktype: ^2.1.0 + typescript: '>=5.0.0' + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0-beta.0 + peerDependenciesMeta: + arktype: + optional: true + typescript: + optional: true + valibot: + optional: true + zod: + optional: true + '@tailwindcss/node@4.1.16': resolution: {integrity: sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==} @@ -2785,6 +2822,18 @@ snapshots: dependencies: tslib: 2.8.1 + '@t3-oss/env-core@0.13.8(typescript@5.9.3)(zod@4.1.12)': + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + + '@t3-oss/env-nextjs@0.13.8(typescript@5.9.3)(zod@4.1.12)': + dependencies: + '@t3-oss/env-core': 0.13.8(typescript@5.9.3)(zod@4.1.12) + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + '@tailwindcss/node@4.1.16': dependencies: '@jridgewell/remapping': 2.3.5 diff --git a/src/env.ts b/src/env.ts index 31d51cd..1bac257 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,14 +1,17 @@ +ort { createEnv } from '@t3-oss/env-nextjs' import { z } from 'zod' -const envSchema = z.object({ - NEXT_PUBLIC_API_BASE_URL: z.url(), - APP_URL: z.url() -}) +export const env = createEnv({ + server: { + APP_URL: z.url() + }, + client: { + NEXT_PUBLIC_API_BASE_URL: z.url() + }, -const parseEnv = envSchema.safeParse(process.env) + runtimeEnv: { + APP_URL: process.env.APP_URL, + NEXT_PUBLIC_API_BASE_URL: process.env.NEXT_PUBLIC_API_BASE_URL + } +}) -if (!parseEnv.success) { - console.error('Invalid environments variables', parseEnv.error) - throw new Error('Invalid environments variables') -} -export const env = parseEnv.data diff --git a/tsconfig.json b/tsconfig.json index 740c06a..82f1fe8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,19 @@ { "compilerOptions": { - "target": "ES2017", + "types": ["cypress"], + "target": "es2022", + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", + "module": "es + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "moduleResolution": "bundler", + "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", @@ -29,7 +34,12 @@ "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts", - "**/*.mts" + + "**/*.mts", + "cypress", + "cypress/**/*.ts", + "cypress/**/*.d.ts" + ], "exclude": ["node_modules"] }