Skip to content

Commit 4283b9c

Browse files
committed
Fix e2e tests to take advantage of BASIC login for fakeuser
1 parent 2ac66ce commit 4283b9c

20 files changed

+210
-126
lines changed

js/e2e-tests/fake-player.mjs

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ export default {
1010

1111
async showLoginOptions(page) {
1212
await page.getByRole("link", { name: /You need to login/ }).click();
13+
14+
await expect(page.getByRole("link", { name: /github/ })).toBeVisible();
15+
await expect(page.getByRole("link", { name: /BASIC/ })).toBeVisible();
1316
},
1417

1518
async login(page) {
1619
await this.showLoginOptions(page);
17-
await page.getByRole("link", { name: /github/ }).click();
18-
// How can we login automatically?
20+
await page.getByRole("link", { name: /BASIC/ }).click();
21+
await page.getByRole("button", { name: /Login fakeUser/ }).click();
1922
},
2023

2124
async playOptimization(page) {

js/e2e-tests/localhost-login-dev.spec.js

-28
This file was deleted.

js/e2e-tests/localhost8080-dev.spec.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ test.beforeAll(async ({ request }) => {
1010
expect(response.ok()).toBeTruthy();
1111
});
1212

13-
// FakeUser skips the login phase
14-
//test('login', async ({ page }) => {
15-
// await page.goto(url);
16-
// await fakePlayer.login(page);
17-
//});
13+
// We just check the login page is working OK
14+
test("showLoginOptions", async ({ page }) => {
15+
await page.goto(url);
16+
await fakePlayer.showLoginOptions(page);
17+
});
18+
19+
test("login", async ({ page }) => {
20+
await page.goto(url);
21+
await fakePlayer.login(page);
22+
});
1823

1924
test("play-optimization", async ({ page }) => {
2025
await page.goto(url);
26+
await fakePlayer.login(page);
2127
await fakePlayer.playOptimization(page);
2228
});

js/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"lint_debug": "eslint --fix src/main/resources/static --debug",
2424
"preview": "vite preview",
2525
"pw_localhost8080": "SPRING_ACTIVE_PROFILES=unsafe,inmemory,fakeuser npx playwright test localhost8080 --project=chromium",
26-
"pw_localhost8080_nofakeuser": "SPRING_ACTIVE_PROFILES=unsafe,inmemory npx playwright test localhost-login --project=chromium",
2726
"pw_localhost8080_ui": "SPRING_ACTIVE_PROFILES=unsafe,inmemory,fakeuser npx playwright test localhost8080 --project=chromium --ui"
2827
},
2928
"type": "module",

js/playwright.config.mjs

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ const config = defineConfig({
3636
},
3737

3838
// https://playwright.dev/docs/test-timeouts
39-
timeout: 5000,
40-
expect: { timeout: 3000 },
39+
timeout: 3000,
40+
expect: { timeout: 2000 },
4141

4242
// https://github.com/microsoft/playwright/issues/14854
4343
use: {

js/src/main/resources/static/index.html

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import KumiteContest from "./ui/js/kumite-contest.js";
5454
import KumiteBoard from "./ui/js/kumite-board.js";
5555
import LoginChecker from "./ui/js/login-checker.js";
56+
import LoginBasic from "./ui/js/login-basic.js";
5657
import AboutView from "./ui/js/about.js";
5758

5859
// Some routes prefix are forbidden as they would match API
@@ -107,6 +108,12 @@
107108
// https://stackoverflow.com/questions/44783787/bind-query-to-props-with-vue-router
108109
// props: route => Object.assign({}, route.query, route.params)
109110
},
111+
{
112+
path: "/html/login/basic",
113+
component: LoginBasic,
114+
// https://stackoverflow.com/questions/44783787/bind-query-to-props-with-vue-router
115+
// props: route => Object.assign({}, route.query, route.params)
116+
},
110117
{ path: "/html/about", component: AboutView },
111118
];
112119

js/src/main/resources/static/ui/js/kumite-account-ref.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default {
1414
...mapState(useKumiteStore, ["nbAccountFetching", "account", "needsToLogin"]),
1515
...mapState(useKumiteStore, {
1616
player(store) {
17-
return store.players[this.playerId] || { status: "not_loaded" };
17+
return store.players[this.playerId] || { error: "not_loaded" };
1818
},
1919
}),
2020
},

js/src/main/resources/static/ui/js/kumite-board-join.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ export default {
2727
...mapState(useKumiteStore, ["nbGameFetching", "nbContestFetching", "nbBoardFetching", "playingPlayerId"]),
2828
...mapState(useKumiteStore, {
2929
game(store) {
30-
return store.games[this.gameId] || { status: "not_loaded" };
30+
return store.games[this.gameId] || { error: "not_loaded" };
3131
},
3232
contest(store) {
33-
return store.contests[this.contestId] || { status: "not_loaded" };
33+
return store.contests[this.contestId] || { error: "not_loaded" };
3434
},
3535
board(store) {
3636
return (
3737
store.contests[this.contestId].board || {
38-
status: "not_loaded",
38+
error: "not_loaded",
3939
}
4040
);
4141
},

js/src/main/resources/static/ui/js/kumite-contest-delete.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,5 @@ export default {
3232

3333
return {};
3434
},
35-
template: /* HTML */ `
36-
<button class="btn btn-danger">Archive this contest (force gameOver)</button>
37-
`,
35+
template: /* HTML */ ` <button class="btn btn-danger">Archive this contest (force gameOver)</button> `,
3836
};

js/src/main/resources/static/ui/js/kumite-contest-form.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ export default {
3333
method: {},
3434
setup(props) {
3535
const store = useKumiteStore();
36-
37-
38-
const contestName = ref('');
36+
37+
const contestName = ref("");
3938
const createdContest = ref({});
4039

4140
const submitContestForm = function () {
@@ -82,7 +81,7 @@ export default {
8281
return { contestName, submitContestForm, createdContest };
8382
},
8483
template: /* HTML */ `
85-
<div v-if="(!game)">
84+
<div v-if="(!game) || game.error">
8685
<div v-if="(nbGameFetching > 0)">
8786
<div class="spinner-border" role="status">
8887
<span class="visually-hidden">Loading gameId={{gameId}}</span>

js/src/main/resources/static/ui/js/kumite-contest-header.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import KumiteContestDelete from "./kumite-contest-delete.js";
99
export default {
1010
components: {
1111
KumiteAccountRef,
12-
KumiteContestDelete,
12+
KumiteContestDelete,
1313
},
1414
props: {
1515
contestId: {
@@ -22,7 +22,7 @@ export default {
2222
},
2323
},
2424
computed: {
25-
...mapState(useKumiteStore, ["nbGameFetching", "nbContestFetching"]),
25+
...mapState(useKumiteStore, ["nbGameFetching", "nbContestFetching", "isLoggedIn", "account"]),
2626
...mapState(useKumiteStore, {
2727
game(store) {
2828
return store.games[this.gameId];
@@ -95,8 +95,8 @@ export default {
9595
<ul>
9696
<li>author: <KumiteAccountRef :accountId="contest.constantMetadata.author" /></li>
9797
<li>created: {{contest.constantMetadata.created}}</li>
98-
<li v-if="contest.constantMetadata.author == account.accountId">
99-
<KumiteContestDelete :contestId="contestId" />
98+
<li v-if="isLoggedIn && contest.constantMetadata.author == account.accountId">
99+
<KumiteContestDelete :gameId="gameId" :contestId="contestId" />
100100
</li>
101101
</ul>
102102
</span>

js/src/main/resources/static/ui/js/kumite-navbar.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { useKumiteStore } from "./store.js";
44
import Logout from "./login-logout.js";
55

66
export default {
7-
components: {
8-
Logout,
9-
},
7+
components: {
8+
Logout,
9+
},
1010
computed: {
1111
...mapState(useKumiteStore, ["needsToLogin", "isLoggedIn", "account", "tokens", "nbAccountFetching", "playingPlayerId"]),
1212
},
@@ -45,17 +45,17 @@ components: {
4545
<div class="collapse navbar-collapse" id="navbarSupportedContent">
4646
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
4747
<li class="nav-item">
48-
<RouterLink class="nav-link" to="/html/games"><i class="bi bi-puzzle"/>Games</RouterLink>
48+
<RouterLink class="nav-link" to="/html/games"><i class="bi bi-puzzle" />Games</RouterLink>
4949
</li>
5050
<li class="nav-item">
51-
<RouterLink class="nav-link" to="/html/contests"><i class="bi bi-trophy"/>Contests</RouterLink>
51+
<RouterLink class="nav-link" to="/html/contests"><i class="bi bi-trophy" />Contests</RouterLink>
5252
</li>
5353
<li class="nav-item">
54-
<RouterLink class="nav-link" to="/html/about"><i class="bi bi-info-lg"/>About</RouterLink>
54+
<RouterLink class="nav-link" to="/html/about"><i class="bi bi-info-lg" />About</RouterLink>
5555
</li>
5656
5757
<li class="nav-item" v-if="isLoggedIn">
58-
<RouterLink class="nav-link" to="/html/me"><i class="bi bi-person"/>Account Settings</RouterLink>
58+
<RouterLink class="nav-link" to="/html/me"><i class="bi bi-person" />Account Settings</RouterLink>
5959
</li>
6060
</ul>
6161
<span v-if="isLoggedIn">

js/src/main/resources/static/ui/js/kumite-player-ref.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default {
1414
...mapState(useKumiteStore, ["nbAccountFetching", "account", "needsToLogin"]),
1515
...mapState(useKumiteStore, {
1616
player(store) {
17-
return store.players[this.playerId] || { status: "not_loaded" };
17+
return store.players[this.playerId] || { error: "not_loaded" };
1818
},
1919
}),
2020
},

js/src/main/resources/static/ui/js/kumite-player.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default {
2121
...mapState(useKumiteStore, ["nbAccountFetching", "account", "needsToLogin"]),
2222
...mapState(useKumiteStore, {
2323
player(store) {
24-
return store.players[this.playerId] || { status: "not_loaded" };
24+
return store.players[this.playerId] || { error: "not_loaded" };
2525
},
2626
}),
2727
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { ref, watch } from "vue";
2+
3+
import { mapState } from "pinia";
4+
import { useKumiteStore } from "./store.js";
5+
6+
import { useRouter } from "vue-router";
7+
import Logout from "./login-logout.js";
8+
9+
export default {
10+
components: {
11+
Logout,
12+
},
13+
props: {
14+
logout: {
15+
type: String,
16+
required: false,
17+
},
18+
},
19+
computed: {
20+
...mapState(useKumiteStore, ["nbAccountFetching", "account", "needsToLogin"]),
21+
...mapState(useKumiteStore, {
22+
user(store) {
23+
return store.account;
24+
},
25+
}),
26+
},
27+
setup(props) {
28+
const store = useKumiteStore();
29+
const router = useRouter();
30+
31+
store.loadUser();
32+
33+
const username = ref("11111111-1111-1111-1111-000000000000");
34+
const password = ref("no_password");
35+
36+
const doLoginBasic = function () {
37+
console.info("Login BASIC");
38+
async function fetchFromUrl(url, csrfToken) {
39+
// https://stackoverflow.com/questions/60265617/how-do-you-include-a-csrf-token-in-a-vue-js-application-with-a-spring-boot-backe
40+
const headers = {
41+
[csrfToken.header]: csrfToken.token,
42+
// https://stackoverflow.com/questions/43842793/basic-authentication-with-fetch
43+
Authorization: "Basic " + btoa(username.value + ":" + password.value),
44+
};
45+
46+
try {
47+
const response = await fetch(url, {
48+
method: "POST",
49+
headers: headers,
50+
});
51+
if (!response.ok) {
52+
throw new Error("Rejected request for logout");
53+
}
54+
55+
const json = await response.json();
56+
57+
console.info("Login BASIC", json);
58+
59+
const loginSuccessHtmlRoute = json.Location;
60+
router.push(loginSuccessHtmlRoute);
61+
} catch (e) {
62+
console.error("Issue on Network: ", e);
63+
}
64+
}
65+
66+
store.fetchCsrfToken().then((csrfToken) => {
67+
fetchFromUrl(`/api/login/v1/basic`, csrfToken);
68+
});
69+
};
70+
71+
return { username, password, doLoginBasic };
72+
},
73+
template: /* HTML */ `
74+
<span v-if="needsToLogin">
75+
<div class="input-group mb-3">
76+
<input type="text" class="form-control" placeholder="Username" aria-label="Username" v-model="username" />
77+
<span class="input-group-text">:</span>
78+
<input type="text" class="form-control" placeholder="Password" aria-label="Password" v-model="password" />
79+
<button type="button" @click="doLoginBasic" class="btn btn-primary">Login fakeUser</button>
80+
</div>
81+
</span>
82+
<span v-else>
83+
<Logout />
84+
</span>
85+
`,
86+
};

js/src/main/resources/static/ui/js/login-checker.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Logout from "./login-logout.js";
1111
export default {
1212
components: {
1313
LoginOptions,
14-
Logout,
14+
Logout,
1515
},
1616
props: {
1717
logout: {
@@ -32,7 +32,7 @@ export default {
3232

3333
store.loadUser();
3434

35-
return { };
35+
return {};
3636
},
3737
template: /* HTML */ `
3838
<div v-if="needsToLogin">
@@ -41,8 +41,6 @@ export default {
4141
<LoginOptions />
4242
</div>
4343
</div>
44-
<div v-else>
45-
Welcome {{user.raw.name}}. <Logout />
46-
</div>
44+
<div v-else>Welcome {{user.raw.name}}. <Logout /></div>
4745
`,
4846
};

0 commit comments

Comments
 (0)