fix(e2e): make server-time element fill width for consistent mask (#283)
* fix(e2e): make server-time element fill width for consistent mask - Add flex layout to .action p to make server-time stretch - Add #server-time flex: 1 rule across all basic-server variants - Update golden screenshots with full-width masked time field This ensures the Playwright mask covers a consistent width regardless of the timestamp content, fixing screenshot comparison flakiness. * fix(e2e): wait for select to be enabled in screenshot generator Match the logic in servers.spec.ts - wait for select to be enabled (servers connected) instead of just visible. * chore: trigger CI re-run
|
|
@ -10,3 +10,9 @@ html, body {
|
||||||
code {
|
code {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
#server-time {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Consistent font for form inputs (inherits from global.css) */
|
/* Consistent font for form inputs (inherits from global.css) */
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,9 @@ html, body {
|
||||||
code {
|
code {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
#server-time {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Consistent font for form inputs (inherits from global.css) */
|
/* Consistent font for form inputs (inherits from global.css) */
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,9 @@ html, body {
|
||||||
code {
|
code {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
#server-time {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Consistent font for form inputs (inherits from global.css) */
|
/* Consistent font for form inputs (inherits from global.css) */
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,13 @@ async function handleOpenLink() {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
|
@ -196,4 +203,10 @@ async function handleOpenLink() {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
:global(#server-time) {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,9 @@ html, body {
|
||||||
code {
|
code {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
#server-time {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Consistent font for form inputs (inherits from global.css) */
|
/* Consistent font for form inputs (inherits from global.css) */
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,13 @@ async function handleOpenLink() {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
|
@ -204,4 +211,10 @@ async function handleOpenLink() {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
:deep(#server-time) {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,9 @@ html, body {
|
||||||
code {
|
code {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time fills remaining width for consistent E2E screenshot masking */
|
||||||
|
#server-time {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server time row: flex layout for consistent mask width in E2E tests */
|
||||||
|
> p {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Consistent font for form inputs (inherits from global.css) */
|
/* Consistent font for form inputs (inherits from global.css) */
|
||||||
textarea,
|
textarea,
|
||||||
input {
|
input {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
* integration-server is excluded (it's for E2E testing, same UI as basic-server-react).
|
* integration-server is excluded (it's for E2E testing, same UI as basic-server-react).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { test, type Page } from "@playwright/test";
|
import { test, expect, type Page } from "@playwright/test";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
|
|
@ -95,12 +95,9 @@ async function waitForAppLoad(page: Page) {
|
||||||
*/
|
*/
|
||||||
async function loadServer(page: Page, serverName: string) {
|
async function loadServer(page: Page, serverName: string) {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await page
|
// Wait for servers to connect (select becomes enabled when servers are ready)
|
||||||
.locator("select")
|
await expect(page.locator("select").first()).toBeEnabled({ timeout: 30000 });
|
||||||
.nth(0)
|
await page.locator("select").first().selectOption({ label: serverName });
|
||||||
.waitFor({ state: "visible", timeout: 30000 });
|
|
||||||
await page.waitForTimeout(500);
|
|
||||||
await page.locator("select").nth(0).selectOption({ label: serverName });
|
|
||||||
await page.click('button:has-text("Call Tool")');
|
await page.click('button:has-text("Call Tool")');
|
||||||
await waitForAppLoad(page);
|
await waitForAppLoad(page);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 48 KiB |