From 5b9f0707b85de2f9c151f2021217bfefc4695425 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Tue, 27 Feb 2024 21:41:34 -0800 Subject: [PATCH 01/37] install cypress and add initial test --- .gitignore | 1 + cypress.config.ts | 7 + cypress/e2e/login.cy.ts | 12 + cypress/support/e2e.ts | 5 + cypress/support/index.d.ts | 11 + cypress/tsconfig.json | 8 + package.json | 4 +- src/app/login/LoginForm.tsx | 19 +- src/components/input/ProfileButton.tsx | 4 +- yarn.lock | 717 ++++++++++++++++++++++++- 10 files changed, 768 insertions(+), 20 deletions(-) create mode 100644 cypress.config.ts create mode 100644 cypress/e2e/login.cy.ts create mode 100644 cypress/support/e2e.ts create mode 100644 cypress/support/index.d.ts create mode 100644 cypress/tsconfig.json diff --git a/.gitignore b/.gitignore index 050397c9..8f39d0f1 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ yarn-error.log* # local env files .env .env.* +*.env.* *.dev.yml diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 00000000..5bed49b8 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: { + baseUrl: 'http://localhost:3000', + }, +}); diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts new file mode 100644 index 00000000..f0490560 --- /dev/null +++ b/cypress/e2e/login.cy.ts @@ -0,0 +1,12 @@ +describe('Login test', () => { + it('logs user in with correct credentials and logs user out', () => { + cy.visit('/login'); + cy.dataCy('input-username').type(Cypress.env('umami_user')); + cy.dataCy('input-password').type(Cypress.env('umami_password')); + cy.dataCy('button-submit').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); + cy.dataCy('button-profile').click(); + cy.dataCy('item-logout').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/login'); + }); +}); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 00000000..2ee2ed8e --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,5 @@ +/// + +Cypress.Commands.add('dataCy', value => { + return cy.get(`[data-cy=${value}]`); +}); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts new file mode 100644 index 00000000..da94c844 --- /dev/null +++ b/cypress/support/index.d.ts @@ -0,0 +1,11 @@ +/// + +declare namespace Cypress { + interface Chainable { + /** + * Custom command to select DOM element by data-cy attribute. + * @example cy.dataCy('greeting') + */ + dataCy(value: string): Chainable>; + } +} diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 00000000..18edb199 --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} diff --git a/package.json b/package.json index 4a38c4e8..422bb475 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "change-password": "node scripts/change-password.js", "lint": "next lint --quiet", "prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install", - "postbuild": "node scripts/postbuild.js" + "postbuild": "node scripts/postbuild.js", + "cypress-open": "cypress open" }, "lint-staged": { "**/*.{js,jsx,ts,tsx}": [ @@ -133,6 +134,7 @@ "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", "cross-env": "^7.0.3", + "cypress": "^13.6.6", "esbuild": "^0.17.17", "eslint": "^8.33.0", "eslint-config-next": "^14.0.4", diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 28d79458..03192413 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -42,17 +42,30 @@ export function LoginForm() {
umami
- + - + - + {formatMessage(labels.login)} diff --git a/src/components/input/ProfileButton.tsx b/src/components/input/ProfileButton.tsx index 11cf1613..4b3c3f7b 100644 --- a/src/components/input/ProfileButton.tsx +++ b/src/components/input/ProfileButton.tsx @@ -25,7 +25,7 @@ export function ProfileButton() { return ( - - - {(close: () => void) => ( - - )} - - - - )} + + + + + {(close: () => void) => ( + + )} + + + Date: Wed, 28 Feb 2024 12:40:23 -0800 Subject: [PATCH 05/37] add orderBy --- src/pages/api/teams/[teamId]/websites/index.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/pages/api/teams/[teamId]/websites/index.ts b/src/pages/api/teams/[teamId]/websites/index.ts index e4919d20..dd2fdeff 100644 --- a/src/pages/api/teams/[teamId]/websites/index.ts +++ b/src/pages/api/teams/[teamId]/websites/index.ts @@ -43,13 +43,7 @@ export default async ( return unauthorized(res); } - const { page, query, pageSize } = req.query; - - const websites = await getTeamWebsites(teamId, { - page, - query, - pageSize, - }); + const websites = await getTeamWebsites(teamId, req.query); return ok(res, websites); } From 44d8606d1aa2e8e059e97e26fc0a6e6fbfd6457b Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Wed, 28 Feb 2024 15:01:13 -0800 Subject: [PATCH 06/37] add cypress docker compose file --- .../cypress.config.ts | 4 ++ cypress/docker-compose.yml | 47 +++++++++++++++++++ cypress/e2e/login.cy.ts | 26 ++++++---- package.json | 3 +- 4 files changed, 69 insertions(+), 11 deletions(-) rename cypress.config.ts => cypress/cypress.config.ts (63%) create mode 100644 cypress/docker-compose.yml diff --git a/cypress.config.ts b/cypress/cypress.config.ts similarity index 63% rename from cypress.config.ts rename to cypress/cypress.config.ts index 5bed49b8..c52aeb49 100644 --- a/cypress.config.ts +++ b/cypress/cypress.config.ts @@ -4,4 +4,8 @@ export default defineConfig({ e2e: { baseUrl: 'http://localhost:3000', }, + env: { + umami_user: 'admin', + umami_password: 'pennydoodoo', + }, }); diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml new file mode 100644 index 00000000..8ce1c938 --- /dev/null +++ b/cypress/docker-compose.yml @@ -0,0 +1,47 @@ +--- +version: '3' +services: + umami: + image: ghcr.io/umami-software/umami:postgresql-latest + ports: + - '3000:3000' + environment: + DATABASE_URL: postgresql://umami:umami@db:5432/umami + DATABASE_TYPE: postgresql + APP_SECRET: replace-me-with-a-random-string + depends_on: + db: + condition: service_healthy + restart: always + healthcheck: + test: ['CMD-SHELL', 'curl http://localhost:3000/api/heartbeat'] + interval: 5s + timeout: 5s + retries: 5 + db: + image: postgres:15-alpine + environment: + POSTGRES_DB: umami + POSTGRES_USER: umami + POSTGRES_PASSWORD: umami + volumes: + - umami-db-data:/var/lib/postgresql/data + restart: always + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'] + interval: 5s + timeout: 5s + retries: 5 + cypress: + image: 'cypress/included:13.6.0' + depends_on: + - umami + - db + environment: + - CYPRESS_baseUrl=http://localhost:3000 + entrypoint: /bin/sh -c "yarn install" + working_dir: /cypress + volumes: + - ./:/cypress +volumes: + umami-db-data: diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts index f0490560..4bd6a6b7 100644 --- a/cypress/e2e/login.cy.ts +++ b/cypress/e2e/login.cy.ts @@ -1,12 +1,18 @@ describe('Login test', () => { - it('logs user in with correct credentials and logs user out', () => { - cy.visit('/login'); - cy.dataCy('input-username').type(Cypress.env('umami_user')); - cy.dataCy('input-password').type(Cypress.env('umami_password')); - cy.dataCy('button-submit').click(); - cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); - cy.dataCy('button-profile').click(); - cy.dataCy('item-logout').click(); - cy.url().should('eq', Cypress.config().baseUrl + '/login'); - }); + it( + 'logs user in with correct credentials and logs user out', + { + defaultCommandTimeout: 10000, + }, + () => { + cy.visit('/login'); + cy.dataCy('input-username').type(Cypress.env('umami_user')); + cy.dataCy('input-password').type(Cypress.env('umami_password')); + cy.dataCy('button-submit').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); + cy.dataCy('button-profile').click(); + cy.dataCy('item-logout').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/login'); + }, + ); }); diff --git a/package.json b/package.json index 24946e3f..16658e2e 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "lint": "next lint --quiet", "prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install", "postbuild": "node scripts/postbuild.js", - "cypress-open": "cypress open" + "cypress-open": "cypress open cypress run --config-file cypress/cypress.config.ts", + "cypress-run": "cypress run cypress run --config-file cypress/cypress.config.ts" }, "lint-staged": { "**/*.{js,jsx,ts,tsx}": [ From 14c0c5060ad1f3556b1665f077406c6a58010b33 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Wed, 28 Feb 2024 16:29:35 -0800 Subject: [PATCH 07/37] working compose file for cypress --- cypress/cypress.config.ts => cypress.config.ts | 4 ---- cypress/docker-compose.yml | 12 ++++++++---- cypress/tsconfig.json | 2 +- package.json | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) rename cypress/cypress.config.ts => cypress.config.ts (63%) diff --git a/cypress/cypress.config.ts b/cypress.config.ts similarity index 63% rename from cypress/cypress.config.ts rename to cypress.config.ts index c52aeb49..5bed49b8 100644 --- a/cypress/cypress.config.ts +++ b/cypress.config.ts @@ -4,8 +4,4 @@ export default defineConfig({ e2e: { baseUrl: 'http://localhost:3000', }, - env: { - umami_user: 'admin', - umami_password: 'pennydoodoo', - }, }); diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml index 8ce1c938..3cd8f546 100644 --- a/cypress/docker-compose.yml +++ b/cypress/docker-compose.yml @@ -2,7 +2,8 @@ version: '3' services: umami: - image: ghcr.io/umami-software/umami:postgresql-latest + build: ../ + #image: ghcr.io/umami-software/umami:postgresql-latest ports: - '3000:3000' environment: @@ -38,10 +39,13 @@ services: - umami - db environment: - - CYPRESS_baseUrl=http://localhost:3000 - entrypoint: /bin/sh -c "yarn install" - working_dir: /cypress + - CYPRESS_baseUrl=http://umami:3000 + - CYPRESS_umami_user=admin + - CYPRESS_umami_password=umami volumes: + - ../tsconfig.json:/tsconfig.json + - ../cypress.config.ts:/cypress.config.ts - ./:/cypress + - ../node_modules/:/node_modules volumes: umami-db-data: diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 18edb199..48c3e14e 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -4,5 +4,5 @@ "lib": ["es5", "dom"], "types": ["cypress", "node"] }, - "include": ["**/*.ts"] + "include": ["**/*.ts", "../cypress.config.ts"] } diff --git a/package.json b/package.json index 16658e2e..895ff334 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,8 @@ "lint": "next lint --quiet", "prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install", "postbuild": "node scripts/postbuild.js", - "cypress-open": "cypress open cypress run --config-file cypress/cypress.config.ts", - "cypress-run": "cypress run cypress run --config-file cypress/cypress.config.ts" + "cypress-open": "cypress open cypress run", + "cypress-run": "cypress run cypress run" }, "lint-staged": { "**/*.{js,jsx,ts,tsx}": [ From 354da4bc560c50441ca6ea99cb108f6847d53ab3 Mon Sep 17 00:00:00 2001 From: Mohanad Alrwaihy Date: Thu, 29 Feb 2024 23:10:41 +0300 Subject: [PATCH 08/37] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Change=20Page=20dir?= =?UTF-8?q?ection=20based=20on=20the=20language=20dir=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/Providers.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/app/Providers.tsx b/src/app/Providers.tsx index 3b4e52e7..bbc10a35 100644 --- a/src/app/Providers.tsx +++ b/src/app/Providers.tsx @@ -5,6 +5,7 @@ import { ReactBasicsProvider } from 'react-basics'; import ErrorBoundary from 'components/common/ErrorBoundary'; import { useLocale } from 'components/hooks'; import 'chartjs-adapter-date-fns'; +import { useEffect } from 'react'; const client = new QueryClient({ defaultOptions: { @@ -16,7 +17,13 @@ const client = new QueryClient({ }); function MessagesProvider({ children }) { - const { locale, messages } = useLocale(); + const { locale, messages, dir } = useLocale(); + + useEffect(() => { + document.documentElement.setAttribute('dir', dir); + document.documentElement.setAttribute('lang', locale); + }, [locale, dir]); + return ( null}> {children} From adf910306b3caa39048952ade88e54ebacb44a01 Mon Sep 17 00:00:00 2001 From: Mohanad Alrwaihy Date: Thu, 29 Feb 2024 23:32:06 +0300 Subject: [PATCH 09/37] =?UTF-8?q?style:=20=F0=9F=8E=A8=20Use=20Logical=20S?= =?UTF-8?q?tyle=20properties=20to=20apply=20same=20styles=20based=20on=20L?= =?UTF-8?q?anguage=20Direction=20(dir)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/reports/[reportId]/ReportBody.module.css | 2 +- src/app/(main)/reports/[reportId]/ReportMenu.module.css | 4 ++-- src/app/(main)/reports/funnel/FunnelChart.module.css | 2 +- .../reports/insights/InsightsParameters.module.css | 2 +- src/app/(main)/settings/teams/WebsiteTags.module.css | 2 +- .../websites/[websiteId]/WebsiteExpandedView.module.css | 2 +- .../(main)/websites/[websiteId]/WebsiteExpandedView.tsx | 5 +++-- .../websites/[websiteId]/realtime/RealtimeLog.module.css | 2 +- src/components/common/ErrorMessage.module.css | 2 +- src/components/common/MobileMenu.module.css | 2 +- src/components/input/LanguageButton.module.css | 2 +- src/components/input/ProfileButton.module.css | 2 +- src/components/input/WebsiteDateFilter.module.css | 9 ++++----- src/components/input/WebsiteDateFilter.tsx | 7 ++++--- src/components/layout/MenuLayout.module.css | 2 +- src/components/layout/NavGroup.module.css | 6 +++--- src/components/layout/PageHeader.module.css | 2 +- src/components/metrics/ActiveUsers.module.css | 4 ++-- src/components/metrics/DatePickerForm.module.css | 8 ++++---- src/components/metrics/ListTable.module.css | 2 +- 20 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/app/(main)/reports/[reportId]/ReportBody.module.css b/src/app/(main)/reports/[reportId]/ReportBody.module.css index 79e3caa0..5fb4259a 100644 --- a/src/app/(main)/reports/[reportId]/ReportBody.module.css +++ b/src/app/(main)/reports/[reportId]/ReportBody.module.css @@ -1,5 +1,5 @@ .body { - padding-left: 20px; + padding-inline-start: 20px; grid-row: 2/3; grid-column: 2 / 3; } diff --git a/src/app/(main)/reports/[reportId]/ReportMenu.module.css b/src/app/(main)/reports/[reportId]/ReportMenu.module.css index 1fc8db29..ee1c6085 100644 --- a/src/app/(main)/reports/[reportId]/ReportMenu.module.css +++ b/src/app/(main)/reports/[reportId]/ReportMenu.module.css @@ -1,7 +1,7 @@ .menu { width: 300px; - padding-right: 20px; - border-right: 1px solid var(--base300); + padding-inline-end: 20px; + border-inline-end: 1px solid var(--base300); grid-row: 2 / 3; grid-column: 1 / 2; } diff --git a/src/app/(main)/reports/funnel/FunnelChart.module.css b/src/app/(main)/reports/funnel/FunnelChart.module.css index c591a54b..0279ea03 100644 --- a/src/app/(main)/reports/funnel/FunnelChart.module.css +++ b/src/app/(main)/reports/funnel/FunnelChart.module.css @@ -63,7 +63,7 @@ .value { color: var(--base50); - margin-right: 20px; + margin-inline-end: 20px; } .track { diff --git a/src/app/(main)/reports/insights/InsightsParameters.module.css b/src/app/(main)/reports/insights/InsightsParameters.module.css index c84f8a9e..ba089b9a 100644 --- a/src/app/(main)/reports/insights/InsightsParameters.module.css +++ b/src/app/(main)/reports/insights/InsightsParameters.module.css @@ -13,5 +13,5 @@ .popup { margin-top: -10px; - margin-left: 30px; + margin-inline-start: 30px; } diff --git a/src/app/(main)/settings/teams/WebsiteTags.module.css b/src/app/(main)/settings/teams/WebsiteTags.module.css index 50ae60a0..5ca7af51 100644 --- a/src/app/(main)/settings/teams/WebsiteTags.module.css +++ b/src/app/(main)/settings/teams/WebsiteTags.module.css @@ -7,5 +7,5 @@ .tag { text-align: center; margin-bottom: 10px; - margin-right: 20px; + margin-inline-end: 20px; } diff --git a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.module.css b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.module.css index b3dcb8d0..f71032ae 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.module.css +++ b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.module.css @@ -58,6 +58,6 @@ gap: 20px; align-items: center; justify-content: space-between; - padding-right: 0; + padding-inline-end: 0; } } diff --git a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx index fcded254..9fdc8fd0 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx @@ -12,7 +12,7 @@ import ReferrersTable from 'components/metrics/ReferrersTable'; import ScreenTable from 'components/metrics/ScreenTable'; import EventsTable from 'components/metrics/EventsTable'; import SideNav from 'components/layout/SideNav'; -import { useNavigation, useMessages } from 'components/hooks'; +import { useNavigation, useMessages, useLocale } from 'components/hooks'; import LinkButton from 'components/common/LinkButton'; import styles from './WebsiteExpandedView.module.css'; @@ -39,6 +39,7 @@ export default function WebsiteExpandedView({ websiteId: string; domainName?: string; }) { + const { dir } = useLocale(); const { formatMessage, labels } = useMessages(); const { router, @@ -122,7 +123,7 @@ export default function WebsiteExpandedView({
- + {formatMessage(labels.back)} diff --git a/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.module.css b/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.module.css index e9c0fc1b..fb5fdecf 100644 --- a/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.module.css +++ b/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.module.css @@ -27,7 +27,7 @@ } .icon { - margin-right: 10px; + margin-inline-end: 10px; } .time { diff --git a/src/components/common/ErrorMessage.module.css b/src/components/common/ErrorMessage.module.css index 391190dc..fe976613 100644 --- a/src/components/common/ErrorMessage.module.css +++ b/src/components/common/ErrorMessage.module.css @@ -11,5 +11,5 @@ } .icon { - margin-right: 10px; + margin-inline-end: 10px; } diff --git a/src/components/common/MobileMenu.module.css b/src/components/common/MobileMenu.module.css index cfe6cf37..63592bec 100644 --- a/src/components/common/MobileMenu.module.css +++ b/src/components/common/MobileMenu.module.css @@ -35,5 +35,5 @@ a.item.selected, .submenu a.item { color: var(--base600); - margin-left: 40px; + margin-inline-start: 40px; } diff --git a/src/components/input/LanguageButton.module.css b/src/components/input/LanguageButton.module.css index cc5d649a..dccb098d 100644 --- a/src/components/input/LanguageButton.module.css +++ b/src/components/input/LanguageButton.module.css @@ -6,7 +6,7 @@ z-index: var(--z-index-popup); border-radius: 5px; border: 1px solid var(--border-color); - margin-left: 10px; + margin-inline-start: 10px; } .item { diff --git a/src/components/input/ProfileButton.module.css b/src/components/input/ProfileButton.module.css index 1eebcab6..37f51f78 100644 --- a/src/components/input/ProfileButton.module.css +++ b/src/components/input/ProfileButton.module.css @@ -18,7 +18,7 @@ font-size: 11px; color: var(--base600); text-align: right; - margin-right: 10px; + margin-inline-end: 10px; } .name { diff --git a/src/components/input/WebsiteDateFilter.module.css b/src/components/input/WebsiteDateFilter.module.css index 6f2e822d..4c17c6be 100644 --- a/src/components/input/WebsiteDateFilter.module.css +++ b/src/components/input/WebsiteDateFilter.module.css @@ -13,12 +13,11 @@ } .buttons button:first-child { - border-top-right-radius: 0; - border-bottom-right-radius: 0; + border-start-end-radius: 0; + border-end-end-radius: 0; } .buttons button:last-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left: 1px solid var(--base400) !important; + border-start-start-radius: 0; + border-end-start-radius: 0; } diff --git a/src/components/input/WebsiteDateFilter.tsx b/src/components/input/WebsiteDateFilter.tsx index 46df3623..17b70c82 100644 --- a/src/components/input/WebsiteDateFilter.tsx +++ b/src/components/input/WebsiteDateFilter.tsx @@ -1,4 +1,4 @@ -import { useDateRange } from 'components/hooks'; +import { useDateRange, useLocale } from 'components/hooks'; import { isAfter } from 'date-fns'; import { getOffsetDateRange } from 'lib/date'; import { Button, Icon, Icons } from 'react-basics'; @@ -7,6 +7,7 @@ import styles from './WebsiteDateFilter.module.css'; import { DateRange } from 'lib/types'; export function WebsiteDateFilter({ websiteId }: { websiteId: string }) { + const { dir } = useLocale(); const [dateRange, setDateRange] = useDateRange(websiteId); const { value, startDate, endDate, offset } = dateRange; const disableForward = @@ -25,12 +26,12 @@ export function WebsiteDateFilter({ websiteId }: { websiteId: string }) { {value !== 'all' && (
diff --git a/src/components/layout/MenuLayout.module.css b/src/components/layout/MenuLayout.module.css index 19162ef5..d2d1b165 100644 --- a/src/components/layout/MenuLayout.module.css +++ b/src/components/layout/MenuLayout.module.css @@ -7,7 +7,7 @@ .menu { width: 240px; padding-top: 34px; - padding-right: 20px; + padding-inline-end: 20px; } .content { diff --git a/src/components/layout/NavGroup.module.css b/src/components/layout/NavGroup.module.css index 9706a001..d827da86 100644 --- a/src/components/layout/NavGroup.module.css +++ b/src/components/layout/NavGroup.module.css @@ -29,12 +29,12 @@ display: flex; flex-direction: row; align-items: center; - border-right: 2px solid var(--base200); + border-inline-end: 2px solid var(--base200); padding: 1rem 2rem; gap: var(--size500); font-weight: 600; width: 200px; - margin-right: -2px; + margin-inline-end: -2px; } a.item { @@ -43,7 +43,7 @@ a.item { .item.selected { color: var(--base900); - border-right-color: var(--primary400); + border-inline-end-color: var(--primary400); background: var(--blue100); } diff --git a/src/components/layout/PageHeader.module.css b/src/components/layout/PageHeader.module.css index 178d8ce4..8e186979 100644 --- a/src/components/layout/PageHeader.module.css +++ b/src/components/layout/PageHeader.module.css @@ -29,7 +29,7 @@ .icon { color: var(--base700); - margin-right: 1rem; + margin-inline-end: 1rem; } .actions { diff --git a/src/components/metrics/ActiveUsers.module.css b/src/components/metrics/ActiveUsers.module.css index 1d87fcd8..5d0a4c7d 100644 --- a/src/components/metrics/ActiveUsers.module.css +++ b/src/components/metrics/ActiveUsers.module.css @@ -1,7 +1,7 @@ .container { display: flex; align-items: center; - margin-left: 20px; + margin-inline-start: 20px; } .text { @@ -13,5 +13,5 @@ .value { font-weight: 600; - margin-right: 4px; + margin-inline-end: 4px; } diff --git a/src/components/metrics/DatePickerForm.module.css b/src/components/metrics/DatePickerForm.module.css index a3d9851d..92a41572 100644 --- a/src/components/metrics/DatePickerForm.module.css +++ b/src/components/metrics/DatePickerForm.module.css @@ -14,9 +14,9 @@ } .calendars > div + div { - margin-left: 20px; - padding-left: 20px; - border-left: 1px solid var(--base300); + margin-inline-start: 20px; + padding-inline-start: 20px; + border-inline-start: 1px solid var(--base300); } .filter { @@ -41,7 +41,7 @@ .calendars > div + div { padding: 0; - margin-left: 0; + margin-inline-start: 0; margin-top: 20px; border: 0; } diff --git a/src/components/metrics/ListTable.module.css b/src/components/metrics/ListTable.module.css index 8f263531..8a0a4916 100644 --- a/src/components/metrics/ListTable.module.css +++ b/src/components/metrics/ListTable.module.css @@ -76,7 +76,7 @@ position: relative; width: 50px; color: var(--base600); - border-left: 1px solid var(--base600); + border-inline-start: 1px solid var(--base600); padding-inline-start: 10px; z-index: 1; } From 54db548832300d2b9890993474345e924d7e7c67 Mon Sep 17 00:00:00 2001 From: Mohanad Alrwaihy Date: Thu, 29 Feb 2024 23:47:59 +0300 Subject: [PATCH 10/37] =?UTF-8?q?refactor:=20=F0=9F=8C=90=20Add=20Missing?= =?UTF-8?q?=20Arabic=20Values?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/intl/messages/ar-SA.json | 54 ++++++++++++++++++--------------- src/lang/ar-SA.json | 47 ++++++++++++++-------------- 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/public/intl/messages/ar-SA.json b/public/intl/messages/ar-SA.json index 6f7c89e6..355868bf 100644 --- a/public/intl/messages/ar-SA.json +++ b/public/intl/messages/ar-SA.json @@ -32,7 +32,7 @@ "label.add-member": [ { "type": 0, - "value": "Add member" + "value": "إضافة عضو" } ], "label.add-website": [ @@ -44,7 +44,7 @@ "label.administrator": [ { "type": 0, - "value": "Administrator" + "value": "مدير" } ], "label.after": [ @@ -215,6 +215,12 @@ "value": "أُنشئت" } ], + "label.created-by": [ + { + "type": 0, + "value": "انشئ من قبل" + } + ], "label.current-password": [ { "type": 0, @@ -272,7 +278,7 @@ "label.delete-report": [ { "type": 0, - "value": "Delete report" + "value": "حذف التقرير" } ], "label.delete-team": [ @@ -332,7 +338,7 @@ "label.does-not-contain": [ { "type": 0, - "value": "Does not contain" + "value": "لا يحتوي" } ], "label.domain": [ @@ -362,7 +368,7 @@ "label.edit-member": [ { "type": 0, - "value": "Edit member" + "value": "تعديل العضو" } ], "label.enable-share-url": [ @@ -380,7 +386,7 @@ "label.event-data": [ { "type": 0, - "value": "Event data" + "value": "تاريخ الحدث" } ], "label.events": [ @@ -588,7 +594,7 @@ "label.manage": [ { "type": 0, - "value": "Manage" + "value": "التحكم" } ], "label.max": [ @@ -600,7 +606,7 @@ "label.member": [ { "type": 0, - "value": "Member" + "value": "عضو" } ], "label.members": [ @@ -630,7 +636,7 @@ "label.my-account": [ { "type": 0, - "value": "My account" + "value": "حسابي" } ], "label.my-websites": [ @@ -694,7 +700,7 @@ "label.ok": [ { "type": 0, - "value": "OK" + "value": "نعم" } ], "label.os": [ @@ -842,7 +848,7 @@ "label.remove-member": [ { "type": 0, - "value": "Remove member" + "value": "حذف عضو" } ], "label.reports": [ @@ -914,7 +920,7 @@ "label.select": [ { "type": 0, - "value": "Select" + "value": "اختيار" } ], "label.select-date": [ @@ -926,7 +932,7 @@ "label.select-role": [ { "type": 0, - "value": "Select role" + "value": "حدد الدور" } ], "label.select-website": [ @@ -1094,7 +1100,7 @@ "label.transfer-website": [ { "type": 0, - "value": "Transfer website" + "value": "حول الموقع" } ], "label.true": [ @@ -1232,7 +1238,7 @@ "message.action-confirmation": [ { "type": 0, - "value": "Type " + "value": "اكتب " }, { "type": 1, @@ -1240,7 +1246,7 @@ }, { "type": 0, - "value": " in the box below to confirm." + "value": " في الصندوق للتأكيد." } ], "message.active-users": [ @@ -1308,7 +1314,7 @@ "message.confirm-remove": [ { "type": 0, - "value": "Are you sure you want to remove " + "value": "هل انت متأكد من حذف " }, { "type": 1, @@ -1336,7 +1342,7 @@ "message.delete-team-warning": [ { "type": 0, - "value": "Deleting a team will also delete all team websites." + "value": "حذف الفريق سيؤدي إلى حذف جميع المواقع" } ], "message.delete-website-warning": [ @@ -1532,25 +1538,25 @@ "message.transfer-team-website-to-user": [ { "type": 0, - "value": "Transfer this website to your account?" + "value": "حول هذا الموقع إلى حسابك؟" } ], "message.transfer-user-website-to-team": [ { "type": 0, - "value": "Select the team to transfer this website to." + "value": "اختر الفريق الذي تريد تحويل الموقع إليه." } ], "message.transfer-website": [ { "type": 0, - "value": "Transfer website ownership to your account or another team." + "value": "حول ملكية الموقع لحسابك أو فريق أخر." } ], "message.triggered-event": [ { "type": 0, - "value": "Triggered event" + "value": "تفعيل حدث" } ], "message.user-deleted": [ @@ -1562,7 +1568,7 @@ "message.viewed-page": [ { "type": 0, - "value": "Viewed page" + "value": "صفحة تمت مشاهدتها" } ], "message.visitor-log": [ @@ -1602,7 +1608,7 @@ "message.visitors-dropped-off": [ { "type": 0, - "value": "Visitors droppped off" + "value": "أنخفض عدد الزوار" } ] } diff --git a/src/lang/ar-SA.json b/src/lang/ar-SA.json index 2e29b76b..22ed595d 100644 --- a/src/lang/ar-SA.json +++ b/src/lang/ar-SA.json @@ -4,9 +4,9 @@ "label.activity-log": "سجل الأحداث", "label.add": "أضِف", "label.add-description": "أضِف وصف", - "label.add-member": "Add member", + "label.add-member": "إضافة عضو", "label.add-website": "إضافة موقع", - "label.administrator": "Administrator", + "label.administrator": "مدير", "label.after": "يعد", "label.all": "الكل", "label.all-time": "كل الوقت", @@ -35,6 +35,7 @@ "label.create-team": "أنشِئ فريق", "label.create-user": "أنشِئ مستخدم", "label.created": "أُنشئت", + "label.created-by": "انشئ من قبل", "label.current-password": "كلمة المرور الحالية", "label.custom-range": "فترة مخصّصة", "label.dashboard": "الشاشة الرئيسية", @@ -44,7 +45,7 @@ "label.day": "يوم", "label.default-date-range": "الفترة المخصّصة الافتراضية", "label.delete": "حذف", - "label.delete-report": "Delete report", + "label.delete-report": "حذف التقرير", "label.delete-team": "حذف الفريق", "label.delete-user": "جذف مستخدم", "label.delete-website": "حذف الموقع", @@ -54,15 +55,15 @@ "label.device": "الجهاز", "label.devices": "الأجهزة", "label.dismiss": "تجاهل", - "label.does-not-contain": "Does not contain", + "label.does-not-contain": "لا يحتوي", "label.domain": "النطاق", "label.dropoff": "إنزال", "label.edit": "عدّل", "label.edit-dashboard": "عدّل لوحة التحكم", - "label.edit-member": "Edit member", + "label.edit-member": "تعديل العضو", "label.enable-share-url": "فعّل مشاركة الرابط", "label.event": "الحدث", - "label.event-data": "Event data", + "label.event-data": "تاريخ الحدث", "label.events": "الأحداث", "label.false": "خطأ", "label.field": "الحقل", @@ -94,20 +95,20 @@ "label.less-than-equals": "أقل مِن أو يساوي", "label.login": "تسجيل الدخول", "label.logout": "تسجيل الخروج", - "label.manage": "Manage", + "label.manage": "التحكم", "label.max": "الحد الأقصى", - "label.member": "Member", + "label.member": "عضو", "label.members": "الأعضاء", "label.min": "الحد الأدنى", "label.mobile": "جوال", "label.more": "المزيد", - "label.my-account": "My account", + "label.my-account": "حسابي", "label.my-websites": "مواقعي", "label.name": "الاسم", "label.new-password": "كلمة مرور جديدة", "label.none": "غير معرّف", "label.number-of-records": "{x} {x, plural, one {record} other {records}}", - "label.ok": "OK", + "label.ok": "نعم", "label.os": "نظام التشغيل", "label.overview": "نظرة عامة", "label.owner": "المالك", @@ -129,7 +130,7 @@ "label.region": "المنطقة", "label.regions": "المناطق", "label.remove": "أزِل", - "label.remove-member": "Remove member", + "label.remove-member": "حذف عضو", "label.reports": "التقارير", "label.required": "اجباري", "label.reset": "اعادة تعيين", @@ -141,9 +142,9 @@ "label.save": "حفظ", "label.screens": "الشاشات", "label.search": "بحث", - "label.select": "Select", + "label.select": "اختيار", "label.select-date": "حدد التاريخ", - "label.select-role": "Select role", + "label.select-role": "حدد الدور", "label.select-website": "حدد موقع", "label.sessions": "الزيارات", "label.settings": "الإعدادات", @@ -171,7 +172,7 @@ "label.total-records": "إجمالي السجلات", "label.tracking-code": "كود التتبع", "label.transfer": "Transfer", - "label.transfer-website": "Transfer website", + "label.transfer-website": "حول الموقع", "label.true": "حقيقي", "label.type": "النوع", "label.unique": "فريد", @@ -194,13 +195,13 @@ "label.websites": "المواقع", "label.window": "النافذة", "label.yesterday": "الأمس", - "message.action-confirmation": "Type {confirmation} in the box below to confirm.", + "message.action-confirmation": "اكتب {confirmation} في الصندوق للتأكيد.", "message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}", "message.confirm-delete": "هل أنت متأكد من حذف {target}?", "message.confirm-leave": "هل أنت متأكد من مغادرة {target}?", - "message.confirm-remove": "Are you sure you want to remove {target}?", + "message.confirm-remove": "هل انت متأكد من حذف {target}?", "message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟", - "message.delete-team-warning": "Deleting a team will also delete all team websites.", + "message.delete-team-warning": "حذف الفريق سيؤدي إلى حذف جميع المواقع", "message.delete-website-warning": "سيتم حذف كافة بيانات الموقع.", "message.error": "حدث خطأ ما.", "message.event-log": "{event} في {url}", @@ -226,12 +227,12 @@ "message.team-not-found": "لم يتم العثور على الفريق", "message.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في الفريق.", "message.tracking-code": "كود التتبع", - "message.transfer-team-website-to-user": "Transfer this website to your account?", - "message.transfer-user-website-to-team": "Select the team to transfer this website to.", - "message.transfer-website": "Transfer website ownership to your account or another team.", - "message.triggered-event": "Triggered event", + "message.transfer-team-website-to-user": "حول هذا الموقع إلى حسابك؟", + "message.transfer-user-website-to-team": "اختر الفريق الذي تريد تحويل الموقع إليه.", + "message.transfer-website": "حول ملكية الموقع لحسابك أو فريق أخر.", + "message.triggered-event": "تفعيل حدث", "message.user-deleted": "تم حذف المستخدم.", - "message.viewed-page": "Viewed page", + "message.viewed-page": "صفحة تمت مشاهدتها", "message.visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}", - "message.visitors-dropped-off": "Visitors droppped off" + "message.visitors-dropped-off": "أنخفض عدد الزوار" } From 7ded5fc6c966ce009ce469c1349ac8f8e72b1779 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Thu, 29 Feb 2024 17:40:49 -0800 Subject: [PATCH 11/37] add prelim website tests --- cypress/e2e/login.cy.ts | 8 +--- cypress/e2e/website.cy.ts | 37 +++++++++++++++++++ cypress/support/e2e.ts | 21 ++++++++++- cypress/support/index.d.ts | 5 +++ .../settings/websites/WebsiteAddButton.tsx | 2 +- .../settings/websites/WebsiteAddForm.tsx | 9 ++++- .../settings/websites/WebsitesTable.tsx | 2 +- 7 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 cypress/e2e/website.cy.ts diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts index 4bd6a6b7..5c833113 100644 --- a/cypress/e2e/login.cy.ts +++ b/cypress/e2e/login.cy.ts @@ -1,15 +1,11 @@ -describe('Login test', () => { +describe('Login tests', () => { it( 'logs user in with correct credentials and logs user out', { defaultCommandTimeout: 10000, }, () => { - cy.visit('/login'); - cy.dataCy('input-username').type(Cypress.env('umami_user')); - cy.dataCy('input-password').type(Cypress.env('umami_password')); - cy.dataCy('button-submit').click(); - cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); + cy.login(Cypress.env('umami_user'), Cypress.env('umami_password')); cy.dataCy('button-profile').click(); cy.dataCy('item-logout').click(); cy.url().should('eq', Cypress.config().baseUrl + '/login'); diff --git a/cypress/e2e/website.cy.ts b/cypress/e2e/website.cy.ts new file mode 100644 index 00000000..86f703eb --- /dev/null +++ b/cypress/e2e/website.cy.ts @@ -0,0 +1,37 @@ +describe('Website tests', () => { + beforeEach(() => { + cy.login(Cypress.env('umami_user'), Cypress.env('umami_password')); + cy.get('a[href="/settings"]').click(); + cy.url().should('include', '/settings/websites'); + }); + + it.skip('Add a website', () => { + cy.dataCy('button-website-add').click(); + cy.contains(/Add website/i).should('be.visible'); + cy.dataCy('input-name').click().type('Test Website', { + delay: 100, + }); + cy.dataCy('input-domain').click().type('testwebsite.com'); + cy.dataCy('button-submit').click(); + cy.get('td[label="Name"]').should('contain.text', 'Test Website'); + cy.get('td[label="Domain"]').should('contain.text', 'testwebsite.com'); + }); + + it('Test tracking script content', () => { + cy.dataCy('link-button-edit').first().click(); + cy.contains(/Tracking code/i).should('be.visible'); + cy.get('div') + .contains(/Tracking code/i) + .click(); + cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script2.js'); + }); + + it('Test tracking script content', () => { + cy.dataCy('link-button-edit').first().click(); + cy.contains(/Tracking code/i).should('be.visible'); + cy.get('div') + .contains(/Tracking code/i) + .click(); + cy.get('textarea').should('contain.text', Cypress.config().baseUrl + '/script.js'); + }); +}); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index 2ee2ed8e..faca6903 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -1,5 +1,24 @@ /// -Cypress.Commands.add('dataCy', value => { +Cypress.Commands.add('dataCy', (value: string) => { return cy.get(`[data-cy=${value}]`); }); + +Cypress.Commands.add('login', (username: string, password: string) => { + cy.session( + [username, password], + () => { + cy.visit('/login'); + cy.dataCy('input-username').type(username); + cy.dataCy('input-password').type(password); + cy.dataCy('button-submit').click(); + cy.url().should('eq', Cypress.config().baseUrl + '/dashboard'); + }, + { + validate: () => { + cy.visit('/profile'); + }, + }, + ); + cy.visit('/dashboard'); +}); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts index da94c844..1da81f1a 100644 --- a/cypress/support/index.d.ts +++ b/cypress/support/index.d.ts @@ -7,5 +7,10 @@ declare namespace Cypress { * @example cy.dataCy('greeting') */ dataCy(value: string): Chainable>; + /** + * Custom command to login user into the app. + * @example cy.login('admin', 'password) + */ + login(username: string, password: string): Chainable>; } } diff --git a/src/app/(main)/settings/websites/WebsiteAddButton.tsx b/src/app/(main)/settings/websites/WebsiteAddButton.tsx index 2c99f22b..5dd60b76 100644 --- a/src/app/(main)/settings/websites/WebsiteAddButton.tsx +++ b/src/app/(main)/settings/websites/WebsiteAddButton.tsx @@ -15,7 +15,7 @@ export function WebsiteAddButton({ teamId, onSave }: { teamId: string; onSave?: return ( - + {(close: () => void) => ( diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx index dac7a8d4..15538661 100644 --- a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx +++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx @@ -27,15 +27,20 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa return ( - + - + - {formatMessage(labels.save)} + + {formatMessage(labels.save)} + ); diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 03192413..3101bf48 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -43,7 +43,7 @@ export function LoginForm() {
@@ -52,7 +52,7 @@ export function LoginForm() { @@ -61,7 +61,7 @@ export function LoginForm() { -