Skip to content

Commit b202d0d

Browse files
committed
Merge remote-tracking branch 'origin/weblate' into weblate
2 parents ff2185c + d33a5b8 commit b202d0d

File tree

13 files changed

+104
-37
lines changed

13 files changed

+104
-37
lines changed

.github/workflows/ui-tests-playwright.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ jobs:
1414
timeout-minutes: 60
1515
runs-on: ubuntu-latest
1616
env:
17-
DEV_PASSWORD: ${{ secrets.DEV_PASSWORD }}
17+
E2E_USER_EMAIL: ${{ secrets.E2E_USER_EMAIL }}
18+
E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
1819
API_BASE_URL: ${{ secrets.API_BASE_URL }}
1920
working-directory: ./frontend
2021
steps:
@@ -65,7 +66,8 @@ jobs:
6566
run: |
6667
cd frontend
6768
touch .env
68-
echo DEV_PASSWORD="${{ secrets.DEV_PASSWORD }}" >> .env
69+
echo E2E_USER_EMAIL="${{ secrets.E2E_USER_EMAIL }}" >> .env
70+
echo E2E_USER_PASSWORD="${{ secrets.E2E_USER_PASSWORD }}" >> .env
6971
echo API_BASE_URL=${{ secrets.API_BASE_URL }} >> .env
7072
cat .env
7173

.vscode/snippets.code-snippets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"",
1010
"import { BtrixElement } from \"@/classes/BtrixElement\";",
1111
"",
12-
"@localized()",
1312
"@customElement(\"btrix-${1:component}\")",
13+
"@localized()",
1414
"export class ${2:Component} extends BtrixElement {",
1515
"\trender() {",
1616
"\t\treturn html``;",

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@
125125
"@open-wc/testing": "^3.2.0",
126126
"@playwright/test": "1.49.0",
127127
"@web/test-runner": "^0.13.22",
128-
"@web/test-runner-playwright": "^0.11.0"
128+
"@web/test-runner-playwright": "^0.11.0",
129+
"http-proxy-middleware": "^2.0.7"
129130
},
130131
"lint-staged": {
131132
"*.{ts,js,html,css,json,webmanifest}": "prettier --write"

frontend/playwright.config.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { defineConfig, devices } from "@playwright/test";
22

3-
/**
4-
* Read environment variables from file.
5-
* https://github.com/motdotla/dotenv
6-
*/
7-
// require('dotenv').config();
3+
if (!process.env.CI) {
4+
/**
5+
* Read environment variables from file.
6+
* https://github.com/motdotla/dotenv
7+
*/
8+
require("dotenv").config({
9+
path: ".env.local",
10+
});
11+
}
812

913
/**
1014
* See https://playwright.dev/docs/test-configuration.

frontend/sample.env.local

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
API_BASE_URL=
22
DOCS_URL=https://docs.browsertrix.com/
3+
E2E_USER_EMAIL=
4+
E2E_USER_PASSWORD=
35
GLITCHTIP_DSN=

frontend/scripts/serve.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ Object.keys(devServer.proxy).forEach((path) => {
2727
app.use(
2828
path,
2929
createProxyMiddleware({
30-
target: devServer.proxy[path],
31-
changeOrigin: true,
30+
...devServer.proxy[path],
31+
followRedirects: true,
3232
}),
3333
);
3434
});

frontend/src/index.ejs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
</head>
2323
<body>
2424
<script>
25+
// Fetch API settings in parallel with dynamically loaded components
2526
window
2627
.fetch("/api/settings", {
2728
headers: { "Content-Type": "application/json" },

frontend/src/index.test.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { NavigateController } from "./controllers/navigate";
66
import { NotifyController } from "./controllers/notify";
77
import { type AppSettings } from "./utils/app";
88
import AuthService from "./utils/AuthService";
9-
import appState, { AppStateService } from "./utils/state";
9+
import { AppStateService } from "./utils/state";
1010
import { formatAPIUser } from "./utils/user";
1111

1212
import { App, type APIUser } from ".";
@@ -62,7 +62,7 @@ describe("browsertrix-app", () => {
6262
expect(el).instanceOf(App);
6363
});
6464

65-
it("renders home when authenticated", async () => {
65+
it("blocks render if settings aren't defined", async () => {
6666
stub(AuthService, "initSessionStorage").returns(
6767
Promise.resolve({
6868
headers: { Authorization: "_fake_headers_" },
@@ -72,25 +72,43 @@ describe("browsertrix-app", () => {
7272
);
7373
// @ts-expect-error checkFreshness is private
7474
stub(AuthService.prototype, "checkFreshness");
75-
stub(appState, "settings").returns(mockAppSettings);
7675
const el = await fixture<App>(html` <browsertrix-app></browsertrix-app>`);
7776
await el.updateComplete;
77+
78+
expect(el.shadowRoot?.childElementCount).to.equal(0);
79+
});
80+
81+
it("renders home when authenticated", async () => {
82+
stub(AuthService, "initSessionStorage").returns(
83+
Promise.resolve({
84+
headers: { Authorization: "_fake_headers_" },
85+
tokenExpiresAt: 0,
86+
username: "test-auth@example.com",
87+
}),
88+
);
89+
// @ts-expect-error checkFreshness is private
90+
stub(AuthService.prototype, "checkFreshness");
91+
const el = await fixture<App>(
92+
html` <browsertrix-app .settings=${mockAppSettings}></browsertrix-app>`,
93+
);
94+
await el.updateComplete;
7895
expect(el.shadowRoot?.querySelector("btrix-home")).to.exist;
7996
});
8097

8198
it("renders home when not authenticated", async () => {
8299
stub(AuthService, "initSessionStorage").returns(Promise.resolve(null));
83100
// @ts-expect-error checkFreshness is private
84101
stub(AuthService.prototype, "checkFreshness");
85-
stub(appState, "settings").returns(mockAppSettings);
86102
stub(NavigateController, "createNavigateEvent").callsFake(
87103
() =>
88104
new CustomEvent("x-ignored", {
89105
detail: { url: "", resetScroll: false },
90106
}),
91107
);
92108

93-
const el = await fixture<App>(html` <browsertrix-app></browsertrix-app>`);
109+
const el = await fixture<App>(
110+
html` <browsertrix-app .settings=${mockAppSettings}></browsertrix-app>`,
111+
);
94112
expect(el.shadowRoot?.querySelector("btrix-home")).to.exist;
95113
});
96114

frontend/src/index.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {
4040
translatedLocales,
4141
type TranslatedLocaleEnum,
4242
} from "@/types/localization";
43-
import { getAppSettings, type AppSettings } from "@/utils/app";
43+
import { type AppSettings } from "@/utils/app";
4444
import { DEFAULT_MAX_SCALE } from "@/utils/crawler";
4545
import localize from "@/utils/localize";
4646
import { toast } from "@/utils/notify";
@@ -70,21 +70,33 @@ export interface UserGuideEventMap {
7070
"btrix-user-guide-show": CustomEvent<{ path?: string }>;
7171
}
7272

73-
@localized()
7473
@customElement("browsertrix-app")
74+
@localized()
7575
export class App extends BtrixElement {
76+
/**
77+
* Browsertrix app version to display in the UI
78+
*/
7679
@property({ type: String })
7780
version?: string;
7881

82+
/**
83+
* Base URL for user guide documentation
84+
*/
7985
@property({ type: String })
8086
docsUrl = "/docs/";
8187

88+
/**
89+
* App settings from `/api/settings`
90+
*/
8291
@property({ type: Object })
8392
settings?: AppSettings;
8493

8594
private readonly router = new APIRouter(ROUTES);
8695
authService = new AuthService();
8796

97+
@state()
98+
private translationReady = false;
99+
88100
@state()
89101
private viewState!: ViewState<typeof ROUTES>;
90102

@@ -116,19 +128,6 @@ export class App extends BtrixElement {
116128
void this.fetchAndUpdateUserInfo();
117129
}
118130

119-
try {
120-
this.settings = await getAppSettings();
121-
} catch (e) {
122-
console.error(e);
123-
this.notify.toast({
124-
message: msg("Couldn’t initialize Browsertrix correctly."),
125-
variant: "danger",
126-
icon: "exclamation-octagon",
127-
id: "get-app-settings-error",
128-
});
129-
} finally {
130-
await localize.initLanguage();
131-
}
132131
super.connectedCallback();
133132

134133
this.addEventListener("btrix-navigate", this.onNavigateTo);
@@ -157,6 +156,10 @@ export class App extends BtrixElement {
157156
willUpdate(changedProperties: Map<string, unknown>) {
158157
if (changedProperties.has("settings")) {
159158
AppStateService.updateSettings(this.settings || null);
159+
160+
if (this.settings && !changedProperties.get("settings")) {
161+
void this.initTranslation();
162+
}
160163
}
161164
if (changedProperties.has("viewState")) {
162165
if (this.viewState.route === "orgs") {
@@ -170,6 +173,13 @@ export class App extends BtrixElement {
170173
}
171174
}
172175

176+
async initTranslation() {
177+
await localize.initLanguage();
178+
// TODO We might want to set this in a lit-localize-status event listener
179+
// see https://lit.dev/docs/localization/runtime-mode/#example-of-using-the-status-event
180+
this.translationReady = true;
181+
}
182+
173183
getLocationPathname() {
174184
return window.location.pathname;
175185
}
@@ -264,6 +274,8 @@ export class App extends BtrixElement {
264274
}
265275

266276
render() {
277+
if (!this.translationReady) return;
278+
267279
return html`
268280
<div class="min-w-screen flex min-h-screen flex-col">
269281
${this.renderNavBar()} ${this.renderAlertBanner()}

frontend/src/pages/account-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ export class AccountSettings extends BtrixElement {
603603
message: msg("Your formatting preference has been updated."),
604604
variant: "success",
605605
icon: "check2-circle",
606+
id: "account-settings-formatting",
606607
});
607608
};
608609
}

0 commit comments

Comments
 (0)