Skip to content

Commit

Permalink
Merge pull request #41 from xenosf/test-cases
Browse files Browse the repository at this point in the history
Add test cases
  • Loading branch information
xenosf authored Nov 13, 2024
2 parents 5ecb9f3 + 1ecfa2f commit d8b1cff
Show file tree
Hide file tree
Showing 38 changed files with 5,501 additions and 503 deletions.
43 changes: 38 additions & 5 deletions .github/workflows/test-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_MATCHING: 3003
directory: .
file_name: .env
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_QUESTION: 3002
envkey_DB_URI_QUESTION: mongodb://localhost:27017/question
directory: .
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_USER: 3001
envkey_DB_URI_USER: mongodb://localhost:27017/user
envkey_JWT_SECRET: secret
Expand Down Expand Up @@ -129,7 +129,7 @@ jobs:
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_COLLABORATION: 3004
directory: .
file_name: .env
Expand Down Expand Up @@ -162,7 +162,7 @@ jobs:
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_AI: 3005
envkey_GEMINI_API_KEY: ''
directory: .
Expand All @@ -173,6 +173,39 @@ jobs:
run: npm ci
- name: Run Tests
run: npm run ci
- name: Upload results to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
chat-service:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ./server/chat-service
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '0'
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Make envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: TEST
envkey_PORT_CHAT: 3006
directory: .
file_name: .env
fail_on_empty: false
sort_keys: false
- name: Install Chat Service Dependencies
run: npm ci
- name: Run Tests
run: npm run ci
- name: Upload results to Codecov
uses: codecov/codecov-action@v4
with:
Expand Down
50 changes: 42 additions & 8 deletions .github/workflows/test-system.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ jobs:
runs-on: ${{ matrix.os }}
env:
BROWSER: ${{ matrix.browser }}
DB_URI: mongodb://172.17.0.1:27017/
DB_URI_QUESTION: mongodb://172.17.0.1:27017/question
DB_URI_USER: mongodb://172.17.0.1:27017/user
NODE_OPTIONS: --max-old-space-size=4096
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -38,16 +42,16 @@ jobs:
- name: Make server envfile
uses: SpicyPizza/[email protected]
with:
envkey_ENV: PROD
envkey_ENV: TEST
envkey_PORT_USER: 3001
envkey_PORT_QUESTION: 3002
envkey_PORT_MATCHING: 3003
envkey_PORT_COLLABORATION: 3004
envkey_PORT_AI: 3005
envkey_PORT_CHAT: 3006
envkey_GEMINI_API_KEY: ''
envkey_DB_URI_QUESTION: mongodb://localhost:27017/question
envkey_DB_URI_USER: mongodb://localhost:27017/user
envkey_DB_URI_QUESTION: ${{ env.DB_URI_QUESTION }}
envkey_DB_URI_USER: ${{ env.DB_URI_USER }}
envkey_JWT_SECRET: secret
directory: server
file_name: .env
Expand All @@ -60,18 +64,48 @@ jobs:
- name: Setup & run server
run: |
cd server
docker compose -f docker-compose.local.yml build
docker compose -f docker-compose.local.yml up -d
docker compose build
docker compose up -d
- name: Setup & run client
run: |
cd client
npm ci
npm run start &
sleep 60
- name: List listening ports & running containers
run: |
sudo netstat -tunlp
docker ps
- name: Run Tests
uses: nick-fields/retry@v3
with:
timeout_seconds: 100
max_attempts: 5
timeout_minutes: 15
max_attempts: 3
retry_on: error
command: xvfb-run --server-args="-screen 0 1024x768x24" npm run test
# - name: Setup tmate session # UNCOMMENT TO BE ABLE TO SSH IN AND DEBUG
# if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 10
- name: Print user service logs
if: ${{ failure() }}
run: docker logs server-user-service-1
- name: Print question service logs
if: ${{ failure() }}
run: docker logs server-qn-service-1
- name: Print collab service logs
if: ${{ failure() }}
run: docker logs server-collab-service-1
- name: Print matching service logs
if: ${{ failure() }}
run: docker logs server-match-service-1
- name: Print AI service logs
if: ${{ failure() }}
run: docker logs server-ai-service-1
- name: Print chat service logs
if: ${{ failure() }}
run: docker logs server-chat-service-1
- name: List listening ports & running containers
if: ${{ failure() }}
run: |
sudo netstat -tunlp
docker ps
22 changes: 22 additions & 0 deletions client/package-lock.json

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

14 changes: 2 additions & 12 deletions client/src/App.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
import { render, screen } from "@testing-library/react";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

test('renders "PeerPrep" text (in toolbar)', () => {
render(
<BrowserRouter>
<App />
</BrowserRouter>
);
const peerprep = screen.getByText(/PeerPrep/i);
expect(peerprep).toBeInTheDocument();
test("placeholder test (major client functionality already tested in e2e)", () => {
expect(true).toBe(true);
});
1 change: 1 addition & 0 deletions client/src/hooks/useAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const AuthContext = createContext({
logout: () => {
const cookies = new Cookies();
cookies.remove("accessToken", { path: "/" });
cookies.remove("userId", { path: "/" });
},
isLoading: true,
});
Expand Down
123 changes: 123 additions & 0 deletions e2e/Questions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
let {
getWebDriver,
findButtonContainingText,
waitForUrl,
click,
findElementWithWait,
} = require("./utils/driver");
let { URLS, TEST_QUESTION } = require("./utils/const");
const { By } = require("selenium-webdriver");
const { resetServer, fillAddQuestionForm, fillUpdateQuestionForm } = require("./utils/utils");
const { getNewTestUser } = require("./utils/users");
const { resetQuestions } = require("./utils/server");
const { signUpAndLogIn } = require("./utils/utils");

describe("Questions test", () => {
let driver;
const user = getNewTestUser();

beforeAll(async () => {
driver = await getWebDriver();
await resetServer();
await signUpAndLogIn(driver, user);
});

afterAll(async () => {
if (driver) await driver.quit();
});

beforeEach(async () => {
await resetQuestions();
});

describe("button on home page brings you to questions page", () => {
test("button on home page brings you to questions page", async () => {
await click(await findButtonContainingText(driver, "Questions List"));
await waitForUrl(driver, URLS.questions);
expect(await driver.getCurrentUrl()).toEqual(URLS.questions);
});
});

describe("simulate viewing question and clicking link", () => {
test("simulate viewing question and clicking link", async () => {
const titleXpath = `//p[contains(normalize-space(), '${TEST_QUESTION.title}')]`;
const descriptionXpath = `//div[contains(@class,'MuiCollapse-entered')][contains(normalize-space(), 'Category: ${TEST_QUESTION.categories}')]`;
const linkXpath = descriptionXpath + "//a";

await driver.get(URLS.questions);

await click(await findElementWithWait(driver, By.xpath(titleXpath)));
// expect correct description to be shown
await findElementWithWait(driver, By.xpath(descriptionXpath));

let link = await findElementWithWait(driver, By.xpath(linkXpath));
expect(await link.getAttribute("href")).toEqual(TEST_QUESTION.link);
});
});

describe("adding question successfully", () => {
test("adding question successfully", async () => {
let newQuestion = { ...TEST_QUESTION };
newQuestion.title = "hello";
let successMsg = `Successfully submitted question “${newQuestion.title}”.`;
let successMsgXpath = `//p[normalize-space()='${successMsg}']`;

await driver.get(URLS.questions);
await click(await findButtonContainingText(driver, "Add question"));
await fillAddQuestionForm(driver, newQuestion);
await expect(findElementWithWait(driver, By.xpath(successMsgXpath))).resolves.not.toThrow();

// check that added question appears in list
await click(await findButtonContainingText(driver, "View questions"));
let newTitleXpath = `//p[contains(normalize-space(), '${newQuestion.title}')]`;
await expect(findElementWithWait(driver, By.xpath(newTitleXpath))).resolves.not.toThrow();
});
});

describe("adding question unsuccessfully", () => {
test("adding question unsuccessfully", async () => {
let failureMsg = `Question with the title "${TEST_QUESTION.title}" already exists.`;
let failureMsgXpath = `//p[normalize-space()='${failureMsg}']`;

await driver.get(URLS.questions);
await click(await findButtonContainingText(driver, "Add question"));
await fillAddQuestionForm(driver, TEST_QUESTION);
await expect(findElementWithWait(driver, By.xpath(failureMsgXpath))).resolves.not.toThrow();
});
});

describe("updating question", () => {
test("updating question", async () => {
let newQuestion = { ...TEST_QUESTION };
newQuestion.title = "hello";
let successMsgXpath = `//div[@role='alert'][contains(normalize-space(), 'Question updated successfully!')]`;
let updateButtonXpath = `//div[contains(normalize-space(), '${TEST_QUESTION.title}')]/button[contains(text(), 'Update/Delete')]`;

await driver.get(URLS.questions);
await click(await findElementWithWait(driver, By.xpath(updateButtonXpath)));
await fillUpdateQuestionForm(driver, newQuestion);
await expect(findElementWithWait(driver, By.xpath(successMsgXpath))).resolves.not.toThrow();
await driver.sleep(3000);
// check that updated question appears in list
await click(await findButtonContainingText(driver, "View questions"));
let newTitleXpath = `//p[contains(normalize-space(), '${newQuestion.title}')]`;
await expect(findElementWithWait(driver, By.xpath(newTitleXpath))).resolves.not.toThrow();
});
});

describe("deleting question", () => {
test("deleting question", async () => {
let successMsgXpath = `//div[@role='alert'][contains(normalize-space(), 'Question deleted successfully!')]`;
let updateButtonXpath = `//div[contains(normalize-space(), '${TEST_QUESTION.title}')]/button[contains(text(), 'Update/Delete')]`;

await driver.get(URLS.questions);
await click(await findElementWithWait(driver, By.xpath(updateButtonXpath)));
await click(await findButtonContainingText(driver, "Delete Question"));
await expect(findElementWithWait(driver, By.xpath(successMsgXpath))).resolves.not.toThrow();
await driver.sleep(3000);
// check that deleted question disappears from list
let titleXpath = `//p[contains(normalize-space(), '${TEST_QUESTION.title}')]`;
await expect(findElementWithWait(driver, By.xpath(titleXpath))).rejects.toThrow();
});
});
});
File renamed without changes.
Loading

0 comments on commit d8b1cff

Please sign in to comment.