Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"resolved": "ghcr.io/azure/azure-dev/azd@sha256:01bbec064fcb34f7c8730b3e3c2cc210699e213419664524982268b2910c4f73",
"integrity": "sha256:01bbec064fcb34f7c8730b3e3c2cc210699e213419664524982268b2910c4f73"
},
"ghcr.io/devcontainers/features/azure-cli:1": {
"version": "1.2.9",
"resolved": "ghcr.io/devcontainers/features/azure-cli@sha256:4549175fbfd3475d1d62e82f6e5425d03954a6ae06027b2515b0ba41a8206417",
"integrity": "sha256:4549175fbfd3475d1d62e82f6e5425d03954a6ae06027b2515b0ba41a8206417"
"ghcr.io/devcontainers/features/azure-cli:": {
"version": "1.3.0",
"resolved": "ghcr.io/devcontainers/features/azure-cli@sha256:d98f1066c077be0fa9d115b718f458bd803e415181b4a96f82a6f5d9f77241ac",
"integrity": "sha256:d98f1066c077be0fa9d115b718f458bd803e415181b4a96f82a6f5d9f77241ac"
},
"ghcr.io/devcontainers/features/docker-in-docker:": {
"version": "2.17.0",
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c",
"integrity": "sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c"
"version": "3.0.1",
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:ca2508495b01ba29eba93e8153772a2daa65eaa86471cc6863fe2a3d21933df9",
"integrity": "sha256:ca2508495b01ba29eba93e8153772a2daa65eaa86471cc6863fe2a3d21933df9"
},
"ghcr.io/devcontainers/features/dotnet:2": {
"version": "2.5.0",
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"version": "10.0"
},
"ghcr.io/devcontainers/features/powershell:2.0.2": {},
"ghcr.io/devcontainers/features/azure-cli:1": {
"ghcr.io/devcontainers/features/azure-cli:": {
"installBicep": true,
"installPowerShell": true
},
Expand Down
20 changes: 16 additions & 4 deletions tests/TechHub.E2E.Tests/Helpers/BlazorHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,11 @@ public static async Task FillBlazorInputAsync(
var escapedValue = value.Replace("\\", "\\\\").Replace("'", "\\'");
var inputSelector = await locator.EvaluateAsync<string>(
"el => el.tagName.toLowerCase() + (el.type ? '[type=' + el.type + ']' : '')");
var targetInputIndex = await locator.EvaluateAsync<int>(
@"el => {
const selector = el.tagName.toLowerCase() + (el.type ? '[type=' + el.type + ']' : '');
return Array.from(document.querySelectorAll(selector)).indexOf(el);
}");
await locator.Page.WaitForConditionAsync($@"
() => {{
if (window.location.href.includes('{urlQueryParam}=')) return true;
Expand All @@ -660,10 +665,17 @@ await locator.Page.WaitForConditionAsync($@"
// returns the first in DOM order which may be the hidden mobile one.
const inputs = document.querySelectorAll('{inputSelector}');
let input = null;
for (const inp of inputs) {{
if (inp.offsetParent !== null || inp.getClientRects().length > 0) {{
input = inp;
break;
// Prefer the originally targeted input index so retries keep firing
// on the same DOM slot (desktop vs mobile variants can coexist).
if ({targetInputIndex} >= 0 && {targetInputIndex} < inputs.length) {{
input = inputs[{targetInputIndex}];
}}
else {{
for (const inp of inputs) {{
if (inp.offsetParent !== null || inp.getClientRects().length > 0) {{
input = inp;
break;
}}
}}
}}
if (!input && inputs.length > 0) input = inputs[0];
Expand Down
11 changes: 4 additions & 7 deletions tests/TechHub.E2E.Tests/Web/GitHubCopilotFeaturesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,15 +424,12 @@ public async Task GitHubCopilotFeatures_TimelineEntry_ExpandCollapse_ShouldWork(
await Page.GotoRelativeAsync(PageUrl);
await Page.WaitForBlazorReadyAsync();

// The first entry auto-expands on page load; use the second entry to test the toggle.
var entries = Page.Locator(".features-timeline-entry");
await Assertions.Expect(entries.First).ToBeVisibleAsync();

var testEntry = entries.Nth(1);
// Don't assume a fixed index is collapsed. Data can contain duplicate slugs,
// which may cause multiple entries to start expanded.
var testEntry = Page.Locator(
".features-timeline-entry:has(.features-timeline-card[aria-expanded='false'])").First;
var testCard = testEntry.Locator(".features-timeline-card");
await Assertions.Expect(testEntry).ToBeVisibleAsync();

// Second entry starts collapsed (only the first entry auto-expands)
await Assertions.Expect(testCard).ToHaveAttributeAsync("aria-expanded", "false");

// Act - Click to expand
Expand Down
Loading