Skip to content

Commit 720a7e9

Browse files
committed
tests
1 parent ddf5015 commit 720a7e9

12 files changed

Lines changed: 146 additions & 67 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ Browser test execution rules:
179179
- GitHub Actions pipelines must expose explicit staged jobs with readable names such as restore, build, supporting tests, browser tests, release publish, and deploy; vague single-job `validate` graphs are not acceptable when the user needs to see pipeline phases clearly in the Actions UI.
180180
- When monitoring long-running GitHub Actions jobs from the terminal, poll with coarse waits of roughly `3-5` minutes between checks; frequent short-interval polling is noise and does not help on multi-minute browser suites.
181181
- Browser acceptance tests must stay on the production-shaped runtime path; do not add or keep `?wasm-debug=1` or similar debug-query scenarios in automated acceptance coverage unless the user explicitly asks for that path.
182+
- Browser acceptance tests must be isolation-safe under in-suite parallelism: each scenario must create and own its own script, storage, and browser context state instead of mutating shared documents, shared pages, or leftover browser storage from another test.
182183
- Do not add Python or ad-hoc runner scripts to bootstrap browser verification. The repo test commands must self-host the app and execute the flows end to end on their own.
183184
- Browser UI scenarios are the primary acceptance gate for this repo. Component and core tests are supporting layers, not the release bar.
184185
- Major user flows MUST be covered by long Playwright scenarios that execute real browser interactions end to end.

src/PrompterOne.Shared/Library/Components/LibraryScriptCard.razor

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,65 +28,68 @@
2828
</svg>
2929
</button>
3030
</TooltipAnchor>
31-
<div class="dcard-dropdown"
32-
data-test="@UiTestIds.Library.CardMenuDropdown(Card.Id)"
33-
@onclick:stopPropagation="true">
34-
<button type="button"
35-
@onclick:stopPropagation="true"
36-
@onclick="HandleOpenScriptAsync">
37-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
38-
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
39-
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
40-
</svg>
41-
@Text(UiTextKey.CommonRename)
42-
</button>
43-
<button type="button"
44-
@onclick:stopPropagation="true"
45-
@onclick="HandleDuplicateScriptAsync"
46-
data-test="@UiTestIds.Library.CardDuplicate(Card.Id)">
47-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
48-
<rect x="9" y="9" width="13" height="13" rx="2" />
49-
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
50-
</svg>
51-
@Text(UiTextKey.CommonDuplicate)
52-
</button>
53-
<div class="dcard-dropdown-group">
54-
<div class="dcard-dropdown-label">@Text(UiTextKey.CommonMoveToEllipsis)</div>
31+
@if (IsMenuOpen)
32+
{
33+
<div class="dcard-dropdown"
34+
data-test="@UiTestIds.Library.CardMenuDropdown(Card.Id)"
35+
@onclick:stopPropagation="true">
5536
<button type="button"
56-
data-test="@UiTestIds.Library.Move(Card.Id, LibrarySelectionKeys.None)"
5737
@onclick:stopPropagation="true"
58-
@onclick="() => HandleMoveScriptAsync(null)">
38+
@onclick="HandleOpenScriptAsync">
5939
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
60-
<line x1="6" y1="6" x2="18" y2="18" />
61-
<line x1="6" y1="18" x2="18" y2="6" />
40+
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
41+
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
6242
</svg>
63-
@Text(UiTextKey.CommonNoFolder)
43+
@Text(UiTextKey.CommonRename)
6444
</button>
65-
@foreach (var folder in FolderOptions)
66-
{
45+
<button type="button"
46+
@onclick:stopPropagation="true"
47+
@onclick="HandleDuplicateScriptAsync"
48+
data-test="@UiTestIds.Library.CardDuplicate(Card.Id)">
49+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
50+
<rect x="9" y="9" width="13" height="13" rx="2" />
51+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
52+
</svg>
53+
@Text(UiTextKey.CommonDuplicate)
54+
</button>
55+
<div class="dcard-dropdown-group">
56+
<div class="dcard-dropdown-label">@Text(UiTextKey.CommonMoveToEllipsis)</div>
6757
<button type="button"
68-
data-test="@UiTestIds.Library.Move(Card.Id, folder.Id)"
58+
data-test="@UiTestIds.Library.Move(Card.Id, LibrarySelectionKeys.None)"
6959
@onclick:stopPropagation="true"
70-
@onclick="() => HandleMoveScriptAsync(folder.Id)">
60+
@onclick="() => HandleMoveScriptAsync(null)">
7161
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
72-
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
62+
<line x1="6" y1="6" x2="18" y2="18" />
63+
<line x1="6" y1="18" x2="18" y2="6" />
7364
</svg>
74-
@folder.Label
65+
@Text(UiTextKey.CommonNoFolder)
7566
</button>
76-
}
67+
@foreach (var folder in FolderOptions)
68+
{
69+
<button type="button"
70+
data-test="@UiTestIds.Library.Move(Card.Id, folder.Id)"
71+
@onclick:stopPropagation="true"
72+
@onclick="() => HandleMoveScriptAsync(folder.Id)">
73+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
74+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
75+
</svg>
76+
@folder.Label
77+
</button>
78+
}
79+
</div>
80+
<div class="dcard-dropdown-sep"></div>
81+
<button type="button"
82+
class="dcard-dropdown-danger"
83+
@onclick:stopPropagation="true"
84+
@onclick="HandleDeleteScriptAsync">
85+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
86+
<polyline points="3,6 5,6 21,6" />
87+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
88+
</svg>
89+
@Text(UiTextKey.CommonDelete)
90+
</button>
7791
</div>
78-
<div class="dcard-dropdown-sep"></div>
79-
<button type="button"
80-
class="dcard-dropdown-danger"
81-
@onclick:stopPropagation="true"
82-
@onclick="HandleDeleteScriptAsync">
83-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
84-
<polyline points="3,6 5,6 21,6" />
85-
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
86-
</svg>
87-
@Text(UiTextKey.CommonDelete)
88-
</button>
89-
</div>
92+
}
9093
</div>
9194
<div class="dcard-inner" data-test="@UiTestIds.Library.CardSurface(Card.Id)">
9295
<div class="dcard-cover @Card.CoverClass">

src/PrompterOne.Shared/wwwroot/media/go-live-output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,8 @@
406406
}
407407

408408
await getSupport().stopRecordingSegment(session);
409-
session.recordingActive = false;
410409
await getSupport().finalizeRecording(session);
410+
session.recordingActive = false;
411411

412412
session.recordingChunks = [];
413413
session.recordingFileHandle = null;

tests/PrompterOne.Web.UITests.Shell/AppShell/OnboardingFlowTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,11 @@ public Task OnboardingReopen_FromSettings_ReturnsToLibraryWithOverlay() =>
9393

9494
await ShellRouteDriver.OpenSettingsAsync(page);
9595
await UiInteractionDriver.ClickAndContinueAsync(page.GetByTestId(UiTestIds.Settings.NavAbout));
96+
await Expect(page.GetByTestId(UiTestIds.Settings.AboutPanel)).ToBeVisibleAsync();
9697

97-
await UiInteractionDriver.ClickAndContinueAsync(page.GetByTestId(UiTestIds.Settings.AboutOnboardingRestart));
98+
await UiInteractionDriver.ClickAndContinueAsync(
99+
page.GetByTestId(UiTestIds.Settings.AboutOnboardingRestart),
100+
noWaitAfter: true);
98101
await BrowserRouteDriver.WaitForRouteAsync(page, BrowserTestConstants.Routes.LibraryWithOnboarding);
99102

100103
await Expect(page.GetByTestId(UiTestIds.Onboarding.Surface)).ToBeVisibleAsync();

tests/PrompterOne.Web.UITests.Shell/Infrastructure/DynamicHostPortTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ await BrowserRouteDriver.OpenPageAsync(
7171
[Test]
7272
public async Task NewPageAsync_DefaultPath_ReusesSharedBrowserStorage()
7373
{
74-
var primaryPage = await _fixture.NewPageAsync();
75-
var secondaryPage = await _fixture.NewPageAsync();
74+
var primaryPage = await _fixture.NewSharedPageAsync(nameof(NewPageAsync_DefaultPath_ReusesSharedBrowserStorage));
75+
var secondaryPage = await _fixture.NewSharedPageAsync(nameof(NewPageAsync_DefaultPath_ReusesSharedBrowserStorage));
7676

7777
try
7878
{
@@ -95,7 +95,7 @@ await primaryPage.EvaluateAsync(
9595
[Test]
9696
public async Task NewPageAsync_AdditionalContext_KeepsBrowserStorageIsolated()
9797
{
98-
var sharedPage = await _fixture.NewPageAsync();
98+
var sharedPage = await _fixture.NewSharedPageAsync(nameof(NewPageAsync_AdditionalContext_KeepsBrowserStorageIsolated));
9999
var isolatedPage = await _fixture.NewPageAsync(additionalContext: true);
100100

101101
try

tests/PrompterOne.Web.UITests.Shell/Library/LibraryFolderOverlayFlowTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ public async Task FolderOverlay_IsTranslucent_AndCreationAcceptsTypedInput()
4646
await Expect(page.GetByTestId(BrowserTestConstants.Elements.RoadshowsFolder)).ToBeVisibleAsync();
4747
await Expect(page.GetByTestId(UiTestIds.Header.LibraryBreadcrumbCurrent)).ToHaveTextAsync(BrowserTestConstants.Folders.RoadshowsName);
4848

49-
await page.ReloadAsync();
50-
await ShellRouteDriver.WaitForLibraryReadyAsync(page);
49+
await BrowserRouteDriver.ReloadPageAsync(
50+
page,
51+
BrowserTestConstants.Routes.Library,
52+
UiTestIds.Library.Page,
53+
"library-folder-overlay-reload");
5154
await Expect(page.GetByTestId(BrowserTestConstants.Elements.RoadshowsFolder)).ToBeVisibleAsync();
5255
await Expect(page.GetByTestId(UiTestIds.Header.LibraryBreadcrumbCurrent)).ToHaveTextAsync(BrowserTestConstants.Folders.RoadshowsName);
5356
}

tests/PrompterOne.Web.UITests.Shell/Library/LibraryScreenFlowTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ await Expect(page.GetByTestId(UiTestIds.Header.LibraryBreadcrumbCurrent))
8383
.ToHaveTextAsync(BrowserTestConstants.Folders.TedTalksName);
8484

8585
await Expect(page.GetByTestId(BrowserTestConstants.Elements.LeadershipCard)).ToContainTextAsync(BrowserTestConstants.Scripts.LeadershipTitle);
86+
var leadershipMenuDropdown = page.GetByTestId(UiTestIds.Library.CardMenuDropdown(BrowserTestConstants.Scripts.LeadershipId));
8687
await UiInteractionDriver.ClickAndContinueAsync(
8788
page.GetByTestId(UiTestIds.Library.CardMenu(BrowserTestConstants.Scripts.LeadershipId)));
89+
await Expect(leadershipMenuDropdown).ToBeVisibleAsync();
8890
await UiInteractionDriver.ClickAndContinueAsync(
8991
page.GetByTestId(UiTestIds.Library.CardDuplicate(BrowserTestConstants.Scripts.LeadershipId)));
9092

@@ -268,8 +270,11 @@ await UiInteractionDriver.ClickAndContinueAsync(
268270
await Expect(page.GetByTestId(BrowserTestConstants.Elements.SecurityIncidentCard)).ToBeHiddenAsync();
269271
await Expect(page.GetByTestId(UiTestIds.Header.LibraryBreadcrumbCurrent)).ToHaveTextAsync(BrowserTestConstants.Folders.RoadshowsName);
270272

271-
await page.ReloadAsync();
272-
await ShellRouteDriver.WaitForLibraryReadyAsync(page);
273+
await BrowserRouteDriver.ReloadPageAsync(
274+
page,
275+
BrowserTestConstants.Routes.Library,
276+
UiTestIds.Library.Page,
277+
"library-create-folder-reload");
273278
await Expect(page.GetByTestId(BrowserTestConstants.Elements.RoadshowsFolder)).ToBeVisibleAsync();
274279
await Expect(page.GetByTestId(BrowserTestConstants.Elements.DemoCard)).ToContainTextAsync(BrowserTestConstants.Scripts.ProductLaunchTitle);
275280
await Expect(page.GetByTestId(BrowserTestConstants.Elements.SecurityIncidentCard)).ToBeHiddenAsync();

tests/PrompterOne.Web.UITests.Shell/Settings/SettingsCrossTabSyncTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ public async Task SettingsAppearance_PropagatesThemeChangesAcrossTabsInSharedCon
1414
{
1515
UiScenarioArtifacts.ResetScenario(BrowserTestConstants.SettingsFlow.CrossTabThemeScenario);
1616

17-
var pages = await _fixture.NewSharedPagesAsync(BrowserTestConstants.SettingsFlow.SharedContextPageCount);
17+
var pages = await _fixture.NewSharedPagesAsync(
18+
BrowserTestConstants.SettingsFlow.SharedContextPageCount,
19+
nameof(SettingsAppearance_PropagatesThemeChangesAcrossTabsInSharedContext));
1820
var primaryPage = pages[0];
1921
var secondaryPage = pages[1];
2022

tests/PrompterOne.Web.UITests.Studio/GoLive/GoLiveFlowTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ await page.WaitForFunctionAsync(
5353
BrowserTestConstants.GoLive.StoredStudioSettingsKey,
5454
new() { Timeout = BrowserTestConstants.Timing.ExtendedVisibleTimeoutMs });
5555

56-
await page.ReloadAsync(new() { WaitUntil = Microsoft.Playwright.WaitUntilState.Load });
56+
await BrowserRouteDriver.ReloadPageAsync(
57+
page,
58+
BrowserTestConstants.Routes.GoLiveDemo,
59+
UiTestIds.GoLive.Page,
60+
"go-live-destination-persistence-reload");
5761

5862
await Expect(page.GetByTestId(UiTestIds.GoLive.VdoToggle))
5963
.ToHaveAttributeAsync(BrowserTestConstants.State.EnabledAttribute, BrowserTestConstants.State.EnabledValue);

tests/PrompterOne.Web.UITests.Studio/GoLive/GoLiveShellSessionFlowTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ await Expect(page.GetByTestId(UiTestIds.Header.GoLive))
102102
[Test]
103103
public async Task GoLivePage_GenericActiveSession_WidgetReturnsToPlainGoLiveRoute_WithoutInjectingEditorScriptId()
104104
{
105-
var pages = await _fixture.NewSharedPagesAsync(BrowserTestConstants.GoLive.SharedContextPageCount);
105+
var pages = await _fixture.NewSharedPagesAsync(
106+
BrowserTestConstants.GoLive.SharedContextPageCount,
107+
nameof(GoLivePage_GenericActiveSession_WidgetReturnsToPlainGoLiveRoute_WithoutInjectingEditorScriptId));
106108
var primaryPage = pages[0];
107109
var secondaryPage = pages[1];
108110

@@ -142,7 +144,9 @@ public async Task GoLivePage_RecordingState_PropagatesAcrossSharedTabsAndReturns
142144
{
143145
UiScenarioArtifacts.ResetScenario(BrowserTestConstants.GoLive.CrossTabIndicatorScenario);
144146

145-
var pages = await _fixture.NewSharedPagesAsync(BrowserTestConstants.GoLive.SharedContextPageCount);
147+
var pages = await _fixture.NewSharedPagesAsync(
148+
BrowserTestConstants.GoLive.SharedContextPageCount,
149+
nameof(GoLivePage_RecordingState_PropagatesAcrossSharedTabsAndReturnsToIdleAfterStop));
146150
var primaryPage = pages[0];
147151
var secondaryPage = pages[1];
148152

0 commit comments

Comments
 (0)