Skip to content

Commit

Permalink
ci: add first integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bacali95 committed Oct 20, 2021
1 parent 74ef99e commit c2b23b2
Show file tree
Hide file tree
Showing 26 changed files with 2,142 additions and 716 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ jobs:
- name: Build Judge
run: docker build -t tunjudge/judge -f docker/judge/Dockerfile .

- name: Run app for testing
run: docker-compose -f docker-compose.test.yml up -d

- name: Integration tests
uses: cypress-io/github-action@v2
with:
working-directory: tests
install: false
browser: chrome
record: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Stop app
run: docker-compose -f docker-compose.test.yml down

- name: Push Images
if: github.ref == 'refs/heads/main'
run: |
Expand Down
695 changes: 21 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ services:
volumes:
- /opt/tun-judge/db-data:/var/lib/postgresql/data
ports:
- 5432:5432
- "5432:5432"

adminer:
image: adminer
restart: always
ports:
- 8081:8080
- "8080:8080"

redis:
image: bitnami/redis:6.0
Expand All @@ -27,7 +27,7 @@ services:
volumes:
- redis-data:/bitnami/redis/data
ports:
- 6379:6379
- "6379:6379"

volumes:
redis-data:
Expand Down
21 changes: 4 additions & 17 deletions docker-compose.yml → docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ version: '3'

services:
server:
build:
context: .
dockerfile: docker/server/Dockerfile
image: tunjudge/server
restart: always
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
Expand All @@ -21,10 +20,8 @@ services:
- redis

judge:
build:
context: .
dockerfile: docker/judge/Dockerfile
restart: on-failure
image: tunjudge/judge
restart: always
environment:
HOSTNAME: judgehost
TUN_JUDGE_URL: http://server:3000
Expand All @@ -45,14 +42,6 @@ services:
POSTGRES_PASSWORD: tun-judge
volumes:
- /opt/tun-judge/db-data:/var/lib/postgresql/data
ports:
- "5432:5432"

adminer:
image: adminer
restart: always
ports:
- "8080:8080"

redis:
image: bitnami/redis:6.0
Expand All @@ -61,8 +50,6 @@ services:
- ALLOW_EMPTY_PASSWORD=yes
volumes:
- redis-data:/bitnami/redis/data
ports:
- "6379:6379"

volumes:
redis-data:
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
"description": "",
"main": "index.js",
"scripts": {
"postinstall": "run-in-all -y install projects/client projects/server projects/judge projects/docs",
"postinstall": "run-in-all -y install projects/client projects/server projects/judge projects/docs tests",
"lint": "run-in-all -y lint projects/client projects/server projects/judge",
"prettier": "prettier --check projects/*/{src,test}/**/*.{ts,tsx}",
"prettier:fix": "prettier --write projects/*/{src,test}/**/*.{ts,tsx}",
"prettier": "prettier --check projects/*/{src,test}/**/*.{ts,tsx} tests/**/*.ts",
"prettier:fix": "prettier --write projects/*/{src,test}/**/*.{ts,tsx} tests/**/*.ts",
"release": "standard-version -a ",
"image:tag-and-push": "node scripts/tag-and-push-image",
"version:current": "node scripts/current-version.js",
"version:new": "yarn version --no-git-tag-version --new-version",
"version:update": "run-in-all --yarn version:new . projects/client projects/server projects/judge --args"
"version:update": "run-in-all --yarn version:new . projects/client projects/server projects/judge projects/docs --args"
},
"keywords": [],
"author": "",
"license": "GPL-3.0",
"license": "MIT",
"dependencies": {
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
Expand Down
4 changes: 2 additions & 2 deletions projects/client/craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ module.exports = {
proxy: [
{
context: ['/api/**'],
target: `http://localhost:3000/`,
target: `http://localhost:3001/`,
},
{
context: ['/socket.io'],
target: `ws://localhost:3000/`,
target: `ws://localhost:3001/`,
ws: true,
},
],
Expand Down
7 changes: 4 additions & 3 deletions projects/client/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "client",
"name": "tun-judge-client",
"version": "0.0.36",
"description": "The client of TunJudge",
"private": true,
"license": "GPL-3.0",
"license": "MIT",
"scripts": {
"start": "REACT_APP_VERSION=$npm_package_version PORT=3002 craco start",
"start": "REACT_APP_VERSION=$npm_package_version craco start",
"build": "REACT_APP_VERSION=$npm_package_version craco build",
"test": "REACT_APP_VERSION=$npm_package_version craco test",
"lint": "eslint \"{src,test}/**/*.ts\"",
Expand Down
7 changes: 6 additions & 1 deletion projects/client/src/pages/shared/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const Login: React.FC = observer(() => {
<TextInput<Credentials>
entity={credentials}
field="username"
name="username"
placeHolder="Username"
autoComplete="username"
required
Expand All @@ -57,14 +58,18 @@ const Login: React.FC = observer(() => {
<TextInput<Credentials>
entity={credentials}
field="password"
name="password"
type="Password"
placeHolder="Password"
autoComplete="username"
required
errors={errors}
setErrors={setErrors}
/>
<button className="p-2 rounded-md text-white bg-blue-500 w-1/4 mx-auto" type="submit">
<button
className="t-login-btn p-2 rounded-md text-white bg-blue-500 w-1/4 mx-auto"
type="submit"
>
Login
</button>
</form>
Expand Down
5 changes: 5 additions & 0 deletions projects/client/src/pages/shared/form-controls/BasicInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TextInputProps } from './TextInput';
import { ColSpanWidth } from './types';

export type BasicInputProps = {
name?: string;
type?: string;
label?: string;
description?: React.ReactNode;
Expand All @@ -31,6 +32,7 @@ type InputProps = BasicInputProps & {
type FullInputProps = InputProps & TextInputProps & NumberInputProps;

const BasicInput: React.FC<FullInputProps> = ({
name,
textarea,
type,
label,
Expand Down Expand Up @@ -101,6 +103,7 @@ const BasicInput: React.FC<FullInputProps> = ({
touched && hasErrors,
}
)}
name={name}
required={required}
readOnly={readOnly}
placeholder={placeHolder ?? label}
Expand All @@ -114,6 +117,7 @@ const BasicInput: React.FC<FullInputProps> = ({
<input
className="h-5 w-5 text-blue-600 border-gray-300 rounded"
type="checkbox"
name={name}
required={required}
readOnly={readOnly}
defaultChecked={defaultValue}
Expand All @@ -129,6 +133,7 @@ const BasicInput: React.FC<FullInputProps> = ({
touched && hasErrors,
}
)}
name={name}
required={required}
readOnly={readOnly}
pattern={pattern}
Expand Down
2 changes: 1 addition & 1 deletion projects/client/src/pages/team/views/SubmitForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const SubmitForm: DataTableItemForm<Submission> = observer(
label="Problem"
required
options={(currentContest?.problems ?? [])
.map((p) => ({ ...p.problem, name: `${p.shortName} - ${p.problem.name}` }))
.slice()
.map((p) => ({ ...p.problem, name: `${p.shortName} - ${p.problem.name}` }))
.sort((a, b) => a.name.localeCompare(b.name))}
optionsTextField="name"
errors={errors}
Expand Down
5 changes: 3 additions & 2 deletions projects/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "docs",
"version": "0.0.0",
"name": "tun-judge-docs",
"version": "0.0.36",
"description": "The documentation of TunJudge",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand Down
2 changes: 1 addition & 1 deletion projects/judge/.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TUN_JUDGE_URL=http://localhost:3000
TUN_JUDGE_URL=http://localhost:3001
TUN_JUDGE_USERNAME=judge-host
TUN_JUDGE_PASSWORD=judge-host
LOG_LEVEL=debug
5 changes: 2 additions & 3 deletions projects/judge/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"name": "tun-judge-judge",
"version": "0.0.36",
"description": "",
"author": "",
"description": "The judge system of TunJudge",
"private": true,
"license": "GPL-3.0",
"license": "MIT",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
Expand Down
5 changes: 2 additions & 3 deletions projects/server/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"name": "tun-judge-server",
"version": "0.0.36",
"description": "",
"author": "",
"description": "The server of TunJudge",
"private": true,
"license": "GPL-3.0",
"license": "MIT",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
Expand Down
2 changes: 1 addition & 1 deletion projects/server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async function bootstrap() {
})
);

await app.listen(3000, '0.0.0.0');
await app.listen(config.nodeEnv === 'development' ? 3001 : 3000, '0.0.0.0');
}

bootstrap();
3 changes: 3 additions & 0 deletions tests/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
plugins: ['cypress'],
};
21 changes: 21 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Dependencies
/node_modules

# Production
/build

# Generated files
cypress/screenshots
cypress/videos
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
7 changes: 7 additions & 0 deletions tests/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"projectId": "n2e3as",
"baseUrl": "http://localhost:3000",
"viewportWidth": 1920,
"viewportHeight": 1080,
"videoCompression": false
}
14 changes: 14 additions & 0 deletions tests/cypress/fixtures/users.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"admin": {
"username": "admin",
"password": "admin"
},
"jury": {
"username": "jury",
"password": "jury"
},
"team": {
"username": "team",
"password": "team"
}
}
28 changes: 28 additions & 0 deletions tests/cypress/integration/1-login/login.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
describe('Authentication', () => {
beforeEach(() => {
cy.clearLocalStorage();
cy.visit('/login');
});

it('should login successfully using the admin account', () => {
cy.fixture('users.json').then((users) => login(users.admin));
});

it('should login successfully using the jury account', () => {
cy.fixture('users.json').then((users) => login(users.jury));
});

it('should login successfully using the team account', () => {
cy.fixture('users.json').then((users) => login(users.team));
});
});

function login(user) {
const { username, password } = user;

cy.get('*[name=username]').type(username);
cy.get('*[name=password]').type(password);
cy.get('.t-login-btn').click();
cy.wait(1000);
cy.getCookie('connect.sid').should('exist');
}
1 change: 1 addition & 0 deletions tests/cypress/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default (on, config) => {};
25 changes: 25 additions & 0 deletions tests/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Loading

0 comments on commit c2b23b2

Please sign in to comment.