Skip to content

Commit

Permalink
feat(web.office): add react uapp
Browse files Browse the repository at this point in the history
ref:MANAGER-15907

Signed-off-by: stif59100 <[email protected]>
  • Loading branch information
stif59100 committed Dec 18, 2024
1 parent 66549d1 commit 7a48a67
Show file tree
Hide file tree
Showing 50 changed files with 1,263 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/manager/apps/web-office/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @ovh-ux/manager-web-office-app

> React app for web office 365
20 changes: 20 additions & 0 deletions packages/manager/apps/web-office/cucumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const isCI = process.env.CI;

module.exports = {
default: {
paths: ['e2e/features/**/*.feature'],
require: [
'../../../../playwright-helpers/bdd-setup.ts',
'e2e/**/*.step.ts',
],
requireModule: ['ts-node/register'],
format: [
'summary',
isCI ? 'progress' : 'progress-bar',
!isCI && ['html', 'e2e/reports/cucumber-results-report.html'],
!isCI && ['usage-json', 'e2e/reports/cucumber-usage-report.json'],
].filter(Boolean),
formatOptions: { snippetInterface: 'async-await' },
retry: 1,
},
};
12 changes: 12 additions & 0 deletions packages/manager/apps/web-office/e2e/features/error.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Feature: Error

Scenario Outline: Display an error if request fails
Given The service to fetch the data is <apiOk>
When User navigates to Home page
Then User "<sees>" the list of data
Then User sees <anyError> error

Examples:
| apiOk | sees | anyError |
| OK | sees | no |
| KO | doesn't see | an |
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Feature: Onboarding page

Scenario: User wants to find informations related to web-office-365
Given User has 0 elements in the Listing page
When User navigates to Listing page
Then User gets redirected to Onboarding page
Then User sees 3 guides
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Given, When, Then } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { ICustomWorld } from '../../../../../../playwright-helpers';
import { ConfigParams, getUrl, setupNetwork } from '../utils';
import { title } from '../../public/translations/listing/Messages_fr_FR.json';
import {
manager_error_page_title,
manager_error_page_action_home_label,
manager_error_page_action_reload_label,
} from '../../public/translations/web-office-365/error/Messages_fr_FR.json';

Given('The service to fetch the data is {word}', function(
this: ICustomWorld<ConfigParams>,
apiState: 'OK' | 'KO',
) {
this.handlersConfig.isKo = apiState === 'KO';
});

When('User navigates to Home page', async function(
this: ICustomWorld<ConfigParams>,
) {
await setupNetwork(this);
await this.page.goto(this.testContext.initialUrl || getUrl('root'), {
waitUntil: 'load',
});
});

Then('User {string} the list of data', async function(
this: ICustomWorld<ConfigParams>,
see: 'sees' | "doesn't see",
) {
if (see === 'sees') {
const titleElement = await this.page.getByText(title);
await expect(titleElement).toBeVisible();
}
});

Then('User sees {word} error', async function(
this: ICustomWorld<ConfigParams>,
anyError: 'an' | 'no',
) {
if (anyError === 'an') {
await expect(this.page.getByText(manager_error_page_title)).toBeVisible();

await expect(
this.page.getByText(manager_error_page_action_home_label),
).toBeVisible();

await expect(
this.page.getByText(manager_error_page_action_reload_label),
).toBeVisible();
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Given, When, Then } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { ICustomWorld } from '../../../../../../playwright-helpers';
import { ConfigParams, getUrl, setupNetwork } from '../utils';

Given('User has {int} elements in the Listing page', function(
this: ICustomWorld<ConfigParams>,
nb: number,
) {
this.handlersConfig.nb = nb;
});

When('User navigates to Listing page', async function(
this: ICustomWorld<ConfigParams>,
) {
await setupNetwork(this);
await this.page.goto(getUrl('listing'), { waitUntil: 'load' });
});

Then('User gets redirected to Onboarding page', async function(
this: ICustomWorld<ConfigParams>,
) {
await expect(this.page).toHaveURL(getUrl('onboarding'));
});

Then('User sees {int} guides', async function(
this: ICustomWorld<ConfigParams>,
nbGuides: number,
) {
const guides = await this.page.locator('osds-tile');
await expect(guides).toHaveCount(nbGuides);
});
7 changes: 7 additions & 0 deletions packages/manager/apps/web-office/e2e/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { urls } from '../../src/routes/routes.constant';

export const appUrl = 'http://localhost:9001/app';

export type AppRoute = keyof typeof urls;

export const getUrl = (route: AppRoute) => `${appUrl}/#${urls[route]}`;
2 changes: 2 additions & 0 deletions packages/manager/apps/web-office/e2e/utils/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './network';
export * from './constants';
28 changes: 28 additions & 0 deletions packages/manager/apps/web-office/e2e/utils/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { BrowserContext } from '@playwright/test';
import {
ICustomWorld,
toPlaywrightMockHandler,
Handler,
} from '../../../../../../playwright-helpers';
import {
GetAuthenticationMocks,
getAuthenticationMocks,
} from '../../../../../../playwright-helpers/mocks/auth';
import { getExampleMocks, GetExampleMocksParams } from '../../mocks';

export type ConfigParams = GetAuthenticationMocks & GetExampleMocksParams;

export const getConfig = (params: ConfigParams): Handler[] =>
[getAuthenticationMocks, getExampleMocks].flatMap((getMocks) =>
getMocks(params),
);

export const setupNetwork = async (world: ICustomWorld) =>
Promise.all(
getConfig({
...((world?.handlersConfig as ConfigParams) || ({} as ConfigParams)),
isAuthMocked: true,
})
.reverse()
.map(toPlaywrightMockHandler(world.context as BrowserContext)),
);
22 changes: 22 additions & 0 deletions packages/manager/apps/web-office/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="mobile-web-app-capable" content="yes" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>OVHcloud</title>
<link rel="shortcut icon" href="images/favicon.png" />
<link rel="apple-touch-icon" href="images/touchicon-180.png" />
</head>
<body>
<noscript>
<strong>
We're sorry but this application doesn't work properly without
JavaScript enabled. Please enable it to continue.
</strong>
</noscript>
<div id="root"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
</html>
11 changes: 11 additions & 0 deletions packages/manager/apps/web-office/mocks/example/example-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"id": 20374
},
{
"id": 20375
},
{
"id": 20379
}
]
30 changes: 30 additions & 0 deletions packages/manager/apps/web-office/mocks/example/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Handler } from '../../../../../../playwright-helpers';
import exampleList from './example-data.json';

export type GetExampleMocksParams = { isKo?: boolean; nb?: number };

export const getExampleMocks = ({
isKo,
nb = Number.POSITIVE_INFINITY,
}: GetExampleMocksParams): Handler[] => [
{
url: '*',
response: isKo
? {
message: 'Example error',
}
: exampleList.slice(0, nb),
status: isKo ? 500 : 200,
api: 'v6',
},
{
url: '*',
response: isKo
? {
message: 'Example error',
}
: exampleList.slice(0, nb),
status: isKo ? 500 : 200,
api: 'v2',
},
];
1 change: 1 addition & 0 deletions packages/manager/apps/web-office/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './example/example';
59 changes: 59 additions & 0 deletions packages/manager/apps/web-office/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "@ovh-ux/manager-web-office-app",
"version": "0.0.0",
"private": true,
"description": "React app for web office 365",
"repository": {
"type": "git",
"url": "git+https://github.com/ovh/manager.git",
"directory": "packages/manager/apps/web-office-365"
},
"license": "BSD-3-Clause",
"author": "OVH SAS",
"scripts": {
"build": "tsc && vite build",
"dev": "tsc && vite",
"start": "lerna exec --stream --scope='@ovh-ux/manager-web-office-app' --include-dependencies -- npm run build --if-present",
"start:dev": "lerna exec --stream --scope='@ovh-ux/manager-web-office-app' --include-dependencies -- npm run dev --if-present",
"start:watch": "lerna exec --stream --parallel --scope='@ovh-ux/manager-web-office-app' --include-dependencies -- npm run dev:watch --if-present",
"test:e2e": "tsc && node ../../../../scripts/run-playwright-bdd.js",
"test:e2e:ci": "tsc && node ../../../../scripts/run-playwright-bdd.js --ci"
},
"dependencies": {
"@ovh-ux/manager-config": "^7.5.3-alpha.0",
"@ovh-ux/manager-core-api": "^0.9.0-alpha.0",
"@ovh-ux/manager-core-utils": "^0.3.0",
"@ovh-ux/manager-react-components": "^1.41.0-alpha.2",
"@ovh-ux/manager-react-core-application": "^0.10.8-alpha.0",
"@ovh-ux/manager-react-shell-client": "^0.8.0-alpha.0",
"@ovh-ux/manager-tailwind-config": "^0.2.0",
"@ovh-ux/request-tagger": "^0.4.0-alpha.0",
"@ovh-ux/shell": "^3.11.0-alpha.0",
"@ovhcloud/ods-common-core": "17.2.2",
"@ovhcloud/ods-common-theming": "17.2.2",
"@ovhcloud/ods-components": "17.2.2",
"@ovhcloud/ods-theme-blue-jeans": "17.2.2",
"@tanstack/react-query": "^5.51.21",
"@tanstack/react-query-devtools": "^5.51.21",
"axios": "^1.1.2",
"clsx": "^1.2.1",
"i18next": "^23.8.2",
"i18next-http-backend": "^2.4.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^14.0.5",
"react-router-dom": "^6.3.0",
"tailwindcss": "^3.4.4"
},
"devDependencies": {
"@cucumber/cucumber": "^10.3.1",
"@ovh-ux/manager-vite-config": "*",
"@playwright/test": "^1.41.2",
"typescript": "^5.1.6",
"vite": "^5.2.13"
},
"regions": [
"CA",
"EU"
]
}
20 changes: 20 additions & 0 deletions packages/manager/apps/web-office/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfig } from '@playwright/test';

export default defineConfig({
workers: 3,
fullyParallel: false,
timeout: 30 * 1000,
reporter: [['html', { open: 'on-failure' }]],
expect: {
timeout: 20000,
},
use: {
// Collect trace when retrying the failed test.
trace: 'retain-on-failure',
},
testMatch: '**/*.e2e.ts',
webServer: {
command: 'yarn run dev',
url: 'http://localhost:9000/',
},
});
6 changes: 6 additions & 0 deletions packages/manager/apps/web-office/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"title": "Dashboard page",
"error_service": "No services info",
"general_informations": "Informations générales",
"tab2": "Tab 2",
"back_link": "Retour à la liste"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"title": "Listing page",
"listing_resultats": "résultats"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"title": "web-office-365",
"description": "Découvrez des services de stockage managés qui s’appuient sur le système de fichiers OpenZFS. Bénéficiez en quelques clics d’espaces de stockage centralisés pour entreposer ou sauvegarder vos données et fichiers.",
"orderButtonLabel": "Commander un web-office-365",
"moreInfoButtonLabel": "En savoir plus sur web-office-365",
"guideCategory": "Tutoriel",
"guide1Title": "Premiers pas avec un web-office-365",
"guide1Description": "Découvrez comment gérer un NAS-HA depuis l'espace-client OVHcloud",
"guide2Title": "Monter votre NAS via un partage NFS",
"guide2Description": "Découvrez comment monter un NAS via un partage NFS",
"guide3Title": "Monter votre NAS sur Windows Server via CIFS",
"guide3Description": "Découvrez comment monter un NAS sur Windows Server via le protocole CIFS"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"title": "Bienvenue uapp",
"crumb": "web-office-365",
"tabs_2": "Tabs 2",
"onboarding": "Onboarding"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"manager_error_page_title": "Oops …!",
"manager_error_page_button_cancel": "Annuler",
"manager_error_page_detail_code": "Code d'erreur : ",
"manager_error_page_action_reload_label": "Réessayer",
"manager_error_page_action_home_label": "Retour à la page d'accueil",
"manager_error_page_default": "Une erreur est survenue lors du chargement de la page."
}
Loading

0 comments on commit 7a48a67

Please sign in to comment.