test(e2e): add data-testid attributes for Playwright e2e (Patch 008 R3.1.e)
Minimal testid additions to 4 renderer files so Playwright can target
stable selectors: table-renderer, cell-{rowId}-{fieldName}, kanban-board,
kanban-column-{label}, kanban-card-{rowId}, calendar-renderer,
inline-editor-input, inline-editor-readonly.
Also adds Dockerfile.e2e for the client build used in docker-compose.e2e.yml.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ea00386877
commit
ba8d8678a0
6 changed files with 116 additions and 6 deletions
|
|
@ -632,3 +632,54 @@ En attendant, le rendu est identique fonctionnellement (HTML table + colonnes de
|
|||
- Decider du sort de l'EE branding ("Powered by Docmost" sur les pages partagees publiques)
|
||||
- Crowdin / i18n : ajouter une cle `appName` au lieu du hardcode et router via `getAppName()`
|
||||
- Strategie : renommer le package npm `docmost` -> `docadenice` quand on aura un build pipeline custom complet (impacte trop d'imports actuellement)
|
||||
|
||||
---
|
||||
|
||||
## Patch 008 — R3.1.e : data-testid pour Playwright e2e
|
||||
|
||||
**Commit** : (local-only, branche `acadenice/main`)
|
||||
**Date** : 2026-05-08
|
||||
**Scope** : ajouts `data-testid` minimaux dans les renderers — aucune logique modifiee
|
||||
|
||||
### Fichiers modifies
|
||||
|
||||
#### `apps/client/src/features/acadenice/database-view/renderers/table-renderer.tsx`
|
||||
|
||||
- `<table>` : ajout `data-testid="table-renderer"` — permet a Playwright de cibler le renderer sans dependre de la structure CSS.
|
||||
- `<td>` : ajout `data-testid={`cell-${row.id}-${field.name}`}` — permet de cibler une cellule specifique par row ID et nom de champ.
|
||||
|
||||
#### `apps/client/src/features/acadenice/database-view/components/inline-editor.tsx`
|
||||
|
||||
- Branche `!canWrite` : ajout `data-testid="inline-editor-readonly"` sur le `<span>` — permet aux tests RBAC de verifier que l'editeur est bien en lecture seule.
|
||||
- Branche `default` (`TextInput`) : ajout `data-testid="inline-editor-input"` — permet de cibler l'input dans les tests d'edition inline.
|
||||
|
||||
#### `apps/client/src/features/acadenice/database-view/renderers/kanban-renderer.tsx`
|
||||
|
||||
- `KanbanCard` wrapper div : ajout `data-testid={`kanban-card-${row.id}`}` — ciblage par row ID pour les tests de drag.
|
||||
- `KanbanColumn` wrapper div : ajout `data-testid={`kanban-column-${column.label}`}` — ciblage par label de colonne.
|
||||
- Board div (DndContext child) : ajout `data-testid="kanban-board"` — detection de la presence du kanban dans la page.
|
||||
|
||||
#### `apps/client/src/features/acadenice/database-view/renderers/calendar-renderer.tsx`
|
||||
|
||||
- Root div du composant : ajout `data-testid="calendar-renderer"` — detection de la presence du calendrier.
|
||||
|
||||
#### `apps/client/Dockerfile.e2e` (nouveau)
|
||||
|
||||
- Cree pour docker-compose.e2e.yml : build Vite du client + serve via `serve@14` sur le port 5173.
|
||||
- Utilise uniquement pour les e2e — pas de changement sur le Dockerfile de production.
|
||||
|
||||
### Raison des choix
|
||||
|
||||
- `data-testid` sur les elements conteneurs plutot que sur les elements internes — plus stable face aux refactors de structure interne.
|
||||
- Pas de `data-testid` sur les elements Mantine (Button, Select, etc.) : ces composants ont leurs propres selectors d'accessibilite (role, aria-label) que Playwright prefere nativement.
|
||||
- Aucun `data-testid` ajoute dans les hooks, services, ou extension Tiptap — non necessaire pour les assertions UI e2e.
|
||||
|
||||
### Tests impactes
|
||||
|
||||
7 scenarios e2e dans `e2e/tests/` utilisent ces testids :
|
||||
- `database-view-insert.spec.ts` : `table-renderer`
|
||||
- `database-view-edit-inline.spec.ts` : `cell-{rowId}-{fieldName}`, `inline-editor-input`
|
||||
- `database-view-realtime-sse.spec.ts` : `table-renderer`
|
||||
- `database-view-rbac-denied.spec.ts` : `inline-editor-readonly`
|
||||
- `database-view-kanban-drag.spec.ts` : `kanban-board`, `kanban-column-{label}`, `kanban-card-{rowId}`
|
||||
- `database-view-calendar-reschedule.spec.ts` : `calendar-renderer`
|
||||
|
|
|
|||
44
apps/client/Dockerfile.e2e
Normal file
44
apps/client/Dockerfile.e2e
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Dockerfile.e2e — DocAdenice client for e2e stack.
|
||||
#
|
||||
# Builds the Vite app and serves it via a lightweight static server.
|
||||
# Used only in docker-compose.e2e.yml — not for production.
|
||||
|
||||
FROM node:22-alpine AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy workspace root (monorepo — client may depend on shared packages).
|
||||
COPY package*.json ./
|
||||
COPY apps/client/package*.json ./apps/client/
|
||||
|
||||
# Install deps.
|
||||
RUN npm ci --workspace=apps/client 2>/dev/null || \
|
||||
(cd apps/client && npm ci)
|
||||
|
||||
COPY . .
|
||||
|
||||
# Build with e2e environment placeholders.
|
||||
# VITE_ vars must be set at build time (Vite inlines them).
|
||||
# In CI they are overridden via docker-compose env: section.
|
||||
ARG VITE_APP_URL=http://localhost:3001
|
||||
ARG VITE_BRIDGE_URL=http://localhost:4001
|
||||
|
||||
ENV VITE_APP_URL=${VITE_APP_URL}
|
||||
ENV VITE_BRIDGE_URL=${VITE_BRIDGE_URL}
|
||||
|
||||
RUN cd apps/client && npm run build
|
||||
|
||||
# --- Serve stage ---
|
||||
FROM node:22-alpine AS serve
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Use serve package to host the built assets.
|
||||
RUN npm install -g serve@14
|
||||
|
||||
COPY --from=build /app/apps/client/dist ./dist
|
||||
|
||||
# serve on port 5173 to match Vite dev server default.
|
||||
EXPOSE 5173
|
||||
|
||||
CMD ["serve", "-s", "dist", "-l", "5173"]
|
||||
|
|
@ -53,7 +53,12 @@ export function InlineEditor({
|
|||
if (!canWrite) {
|
||||
return (
|
||||
<Tooltip label={t("database_view.edit.permission_denied")} withArrow>
|
||||
<span className={styles.readOnly}>{formatDisplayValue(initialValue)}</span>
|
||||
<span
|
||||
className={styles.readOnly}
|
||||
data-testid="inline-editor-readonly"
|
||||
>
|
||||
{formatDisplayValue(initialValue)}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
@ -171,6 +176,7 @@ export function InlineEditor({
|
|||
onKeyDown={handleKeyDown}
|
||||
className={styles.input}
|
||||
size="xs"
|
||||
data-testid="inline-editor-input"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ export function CalendarRenderer({ tableId, viewId, bridgeUrl }: CalendarRendere
|
|||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div data-testid="calendar-renderer">
|
||||
<div className={styles.toolbar}>
|
||||
<SegmentedControl
|
||||
size="xs"
|
||||
|
|
|
|||
|
|
@ -161,7 +161,12 @@ function KanbanCard({ row, primaryField, canWrite, onRename }: KanbanCardProps)
|
|||
};
|
||||
|
||||
return (
|
||||
<div ref={setNodeRef} style={style} className={styles.cardWrapper}>
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
style={style}
|
||||
className={styles.cardWrapper}
|
||||
data-testid={`kanban-card-${row.id}`}
|
||||
>
|
||||
<Card
|
||||
shadow="xs"
|
||||
padding="xs"
|
||||
|
|
@ -207,7 +212,10 @@ function KanbanColumn({ column, primaryField, canWrite, onCardRename }: KanbanCo
|
|||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className={styles.column}>
|
||||
<div
|
||||
className={styles.column}
|
||||
data-testid={`kanban-column-${column.label}`}
|
||||
>
|
||||
<div className={styles.columnHeader}>
|
||||
<Text size="sm" fw={600} className={styles.columnTitle}>
|
||||
{column.label}
|
||||
|
|
@ -391,7 +399,7 @@ export function KanbanRenderer({ tableId, viewId, bridgeUrl }: KanbanRendererPro
|
|||
onDragStart={handleDragStart}
|
||||
onDragEnd={handleDragEnd}
|
||||
>
|
||||
<div className={styles.board}>
|
||||
<div className={styles.board} data-testid="kanban-board">
|
||||
{columns.map((col) => (
|
||||
<KanbanColumn
|
||||
key={col.id}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ function TableBody({
|
|||
<td
|
||||
key={field.id}
|
||||
className={styles.td}
|
||||
data-testid={`cell-${row.id}-${field.name}`}
|
||||
onDoubleClick={() => {
|
||||
if (!isEditing) {
|
||||
onCellDoubleClick(row.id, field.id);
|
||||
|
|
@ -207,7 +208,7 @@ export function TableRenderer({ tableId, viewId, bridgeUrl }: TableRendererProps
|
|||
return (
|
||||
<div>
|
||||
<div className={styles.wrapper}>
|
||||
<table className={styles.table}>
|
||||
<table className={styles.table} data-testid="table-renderer">
|
||||
<thead>
|
||||
<tr>
|
||||
{fields.map((field) => (
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue