Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# workflow to check if E2E testing is working properly

name: Playwright Tests
Comment thread
Sanketmundada marked this conversation as resolved.
Outdated
on:
pull_request:
branches:
- master
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,20 @@ This will launch the app on [http://localhost:3000](http://localhost:3000). The
1. Update `docker-compose.yml` file with the following code:

```yaml
version: "3.8"
version: '3.8'

services:
dicedb:
image: dicedb/dicedb:latest
ports:
- "7379:7379"
- '7379:7379'

backend:
build:
context: .
dockerfile: Dockerfile_Backend
ports:
- "8080:8080"
- '8080:8080'
depends_on:
- dicedb
environment:
Expand Down Expand Up @@ -144,6 +144,24 @@ To get the test coverage of the project, execute the following command:
npm run test:coverage
```

To run the E2E test cases, execute the following command:

```bash
npm run test:e2e
```

To get the test report, execute the following command:

```bash
npm run test:e2e-report
```

To run E2E test in interactive mode, execute the following command:

```bash
npm run test:e2e -- --ui
```

## Project Structure

The main components of the DiceDB Playground include:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
depends_on:
- dicedb
environment:
- DICE_ADDR=dicedb:7379
- DICEDB_ADDR=dicedb:7379

frontend:
build:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
depends_on:
- dicedb
environment:
- DICE_ADDR=dicedb:7379
- DICEDB_ADDR=dicedb:7379

frontend:
build:
Expand Down
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const createJestConfig = nextJest({

// Add any custom config to be passed to Jest
const config: Config = {
roots: ['<rootDir>/src'],
coverageProvider: 'v8',
testEnvironment: 'jsdom',
moduleNameMapper: {
Expand Down
60 changes: 60 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"prettier:format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css}\"",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
"test:coverage": "jest --coverage",
"test:e2e": "npx playwright test",
"test:e2e-report": "npx playwright show-report"
},
"dependencies": {
"@emotion/react": "^11.13.3",
Expand All @@ -28,6 +30,7 @@
"sharp": "^0.33.5"
},
"devDependencies": {
"@playwright/test": "^1.47.2",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
Expand Down
41 changes: 41 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Lets also use GitHub reporter here

/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
timeout: 30000,
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
timeout: 30000,
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
timeout: 30000,
},
],
});
2 changes: 1 addition & 1 deletion src/components/Shell/Shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function Shell({ decreaseCommandsLeft }: ShellProps) {
{output.map((line, index) => (
<div
key={index}
data-testid="terminal-output"
data-testid={`terminal-output-${index + 1}`}
className="text-white p-1"
>
{line}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Shell/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('Shell Component', () => {
const { cliInputElement, user, getByTestId } = setupTest();

await user.type(cliInputElement, 'EXEC{enter}');
const terminalOutputElement = getByTestId('terminal-output');
const terminalOutputElement = getByTestId('terminal-output-1');
expect(terminalOutputElement).toHaveTextContent(
"(error) ERR unknown command 'EXEC'",
);
Expand Down
104 changes: 104 additions & 0 deletions tests/playground.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { test, expect } from '@playwright/test';
import type { Page } from '@playwright/test';

const runCommand = async (page: Page, cmd: string) => {
const cmdInput = page.getByTestId('shell-input');
await cmdInput.fill(cmd);
await page.keyboard.press('Enter');
};

test.describe('[Playground Component]', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000');
const cmdInput = page.getByTestId('shell-input');
await expect(cmdInput).toBeVisible();
});

test('should execute SET command properly', async ({ page }) => {
let outputIdx = 0;

// Happy case
await runCommand(page, 'SET foo bar');
// Adding 2 to outputIndex after each command execution
// Reason: 2 items are added to output after each execution, 1st is command itself and 2nd is its result
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'OK',
);

// Error case: SET with wrong number of arguments
await runCommand(page, 'SET foo');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
"(error) ERR wrong number of arguments for 'set' command",
);
});

test('should execute GET command properly', async ({ page }) => {
let outputIdx = 0;

// Happy case
await runCommand(page, 'SET foo bar');
outputIdx += 2;
await runCommand(page, 'GET foo');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();

await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'bar',
);

// Error case for wrong key get
await runCommand(page, 'GET foo1');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'(nil)',
);

// Error case: GET with wrong number of arguments
await runCommand(page, 'GET foo bar');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
"(error) ERR wrong number of arguments for 'get' command",
);
});

test('should execute DEL command properly', async ({ page }) => {
let outputIdx = 0;

// Happy case
await runCommand(page, 'SET foo bar');
outputIdx += 2;
await runCommand(page, 'GET foo');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'bar',
);
await runCommand(page, 'DEL foo');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'1',
);
await runCommand(page, 'GET foo');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
// Getting back the deleted key should return (nil) output
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'(nil)',
);

// Error case: DEL key which is not present
await runCommand(page, 'DEL bar');
outputIdx += 2;
await page.getByTestId(`terminal-output-${outputIdx}`).waitFor();
await expect(page.getByTestId(`terminal-output-${outputIdx}`)).toHaveText(
'0',
);
});
});