mirror of
https://github.com/Kong/insomnia.git
synced 2026-11-06 04:53:59 -05:00
feat(insomnia-test): enhance credential menus and improve spec handling
This commit is contained in:
6 files changed
+61
-42
No files matched your search
@@ -27,6 +27,20 @@ export class PreferencesCredentialsComponent extends PreferencesTabComponent {
|
||||
await this.tabs.tabByName("Credentials").click();
|
||||
}
|
||||
|
||||
private createGitCredentialMenu(): DropdownComponent {
|
||||
return new DropdownComponent(
|
||||
this.page,
|
||||
this.dialog.getByRole("button", { name: "Create Git Credential" }),
|
||||
);
|
||||
}
|
||||
|
||||
private createCloudCredentialMenu(): DropdownComponent {
|
||||
return new DropdownComponent(
|
||||
this.page,
|
||||
this.dialog.getByRole("button", { name: "Create Cloud Credential" }),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom (username/PAT) Git credential from the Credentials tab,
|
||||
* which must already be open (see `openCredentialsTab()`).
|
||||
@@ -38,9 +52,7 @@ export class PreferencesCredentialsComponent extends PreferencesTabComponent {
|
||||
name: /Access Token Credential/,
|
||||
}),
|
||||
);
|
||||
await DropdownComponent.byLabel(this.page, "Create Git Credential").select(
|
||||
"Access Token",
|
||||
);
|
||||
await this.createGitCredentialMenu().select("Access Token");
|
||||
await this.page.getByLabel("Author Email").fill(credential.authorEmail);
|
||||
await this.page.getByLabel("Author Name").fill(credential.authorName);
|
||||
await this.page.getByLabel("Username").fill(credential.username);
|
||||
@@ -63,10 +75,7 @@ export class PreferencesCredentialsComponent extends PreferencesTabComponent {
|
||||
async createAwsCloudCredential(
|
||||
credential: Omit<AwsCloudCredential, "provider">,
|
||||
): Promise<void> {
|
||||
await new DropdownComponent(
|
||||
this.page,
|
||||
this.dialog.getByRole("button", { name: "Create Cloud Credential" }),
|
||||
).select("AWS", false);
|
||||
await this.createCloudCredentialMenu().select("AWS", false);
|
||||
const modal = new ModalComponent(
|
||||
this.page,
|
||||
this.page.getByRole("dialog", {
|
||||
@@ -98,10 +107,7 @@ export class PreferencesCredentialsComponent extends PreferencesTabComponent {
|
||||
async createGcpCloudCredential(
|
||||
credential: Omit<GcpCloudCredential, "provider">,
|
||||
): Promise<void> {
|
||||
await new DropdownComponent(
|
||||
this.page,
|
||||
this.dialog.getByRole("button", { name: "Create Cloud Credential" }),
|
||||
).select("GCP", false);
|
||||
await this.createCloudCredentialMenu().select("GCP", false);
|
||||
const modal = new ModalComponent(
|
||||
this.page,
|
||||
this.page.getByRole("dialog", {
|
||||
@@ -131,10 +137,7 @@ export class PreferencesCredentialsComponent extends PreferencesTabComponent {
|
||||
async createHashiCorpCloudCredential(
|
||||
credential: Omit<HashiCorpCloudCredential, "provider">,
|
||||
): Promise<void> {
|
||||
await new DropdownComponent(
|
||||
this.page,
|
||||
this.dialog.getByRole("button", { name: "Create Cloud Credential" }),
|
||||
).select("HashiCorp", false);
|
||||
await this.createCloudCredentialMenu().select("HashiCorp", false);
|
||||
const modal = new ModalComponent(
|
||||
this.page,
|
||||
this.page.getByRole("dialog", {
|
||||
|
||||
@@ -245,12 +245,15 @@ export class SpecPage extends BasePage {
|
||||
* all.
|
||||
*/
|
||||
async getOpenApiVersion(): Promise<string> {
|
||||
const label = this.page
|
||||
.locator(this.PANE_ONE)
|
||||
.first()
|
||||
.getByText(/OpenAPI \d/)
|
||||
.first();
|
||||
if ((await label.count()) === 0) return "";
|
||||
// The span is always rendered once the spec has content, but stays
|
||||
// empty until the parsed spec's `openapi` field is known, so wait for
|
||||
// text rather than for the element.
|
||||
const label = this.page.getByTestId("spec-openapi-version");
|
||||
try {
|
||||
await expect(label).toHaveText(/OpenAPI \d/, { timeout: DEFAULT_TIMEOUT });
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
return (await label.innerText()).trim();
|
||||
}
|
||||
|
||||
@@ -379,10 +382,14 @@ export class SpecPage extends BasePage {
|
||||
* Reads every suite name currently listed in the Test Suites sidebar.
|
||||
*/
|
||||
async getTestSuiteNames(): Promise<string[]> {
|
||||
return new TableComponent(
|
||||
this.page,
|
||||
this.page.locator(this.TEST_SUITES_LIST),
|
||||
).rows.allInnerTexts();
|
||||
// Re-opening the Tests tab re-renders the list; wait for it to settle
|
||||
// so a read taken mid-render doesn't return a stale or partial list.
|
||||
return this.waitForStableValue(() =>
|
||||
new TableComponent(
|
||||
this.page,
|
||||
this.page.locator(this.TEST_SUITES_LIST),
|
||||
).rows.allInnerTexts(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1144,18 +1144,20 @@ export class WorkspacePage extends BasePage {
|
||||
|
||||
const target = indicator.first();
|
||||
const folderBadge = target.getByTestId("drop-indicator-folder-name");
|
||||
// The sidebar tags its indicator marker (the "on" wrapper, folder-name
|
||||
// badge or dot) with `data-valid` and `data-drop-position`. An invalid
|
||||
// target may render without the marker or the aria label, so only read
|
||||
// what is actually present rather than letting getAttribute() wait out
|
||||
// the full action timeout.
|
||||
const marker = target.locator("[data-drop-position]").first();
|
||||
const dropLabel = target.locator('[aria-roledescription="drop indicator"]');
|
||||
const hasMarker = (await marker.count()) > 0;
|
||||
const [ariaLabel, folderName] = await Promise.all([
|
||||
target
|
||||
.locator('[aria-roledescription="drop indicator"]')
|
||||
.getAttribute("aria-label"),
|
||||
(await dropLabel.count()) > 0 ? dropLabel.first().getAttribute("aria-label") : null,
|
||||
(await folderBadge.count()) > 0 ? folderBadge.innerText() : "",
|
||||
]);
|
||||
// react-aria labels an "on" drop "Drop on <name>"; line drops say
|
||||
// "Insert ...".
|
||||
const isValid =
|
||||
(await target.locator("[data-valid]").first().getAttribute("data-valid")) ===
|
||||
"true";
|
||||
const isInto = (ariaLabel ?? "").startsWith("Drop on");
|
||||
const isValid = hasMarker && (await marker.getAttribute("data-valid")) === "true";
|
||||
const isInto = hasMarker && (await marker.getAttribute("data-drop-position")) === "on";
|
||||
const between = ariaLabel?.match(/^Insert between (.+) and (.+)$/);
|
||||
|
||||
return {
|
||||
|
||||
@@ -23,7 +23,5 @@ test("Verify Renaming And Deleting A Project Via The Dashboard", async ({
|
||||
|
||||
expect(foundByNewName?.id).toBe(project.id);
|
||||
expect(foundByOldName).toBeUndefined();
|
||||
await expect
|
||||
.poll(() => workspaceFlow.getProject(newName), { timeout: 10_000 })
|
||||
.toBeUndefined();
|
||||
expect(await workspaceFlow.getProject(newName)).toBeUndefined();
|
||||
});
|
||||
+13
-4
@@ -535,10 +535,17 @@ function SidebarDropIndicator({
|
||||
className={`absolute right-1 left-1 z-10 flex items-center rounded-sm outline-2 outline-solid ${outlineClass}`}
|
||||
style={{ transform: `translateY(${rowStart}px)`, height: `${rowHeight}px` }}
|
||||
>
|
||||
<Icon
|
||||
icon="turn-down"
|
||||
className={`ml-2 h-3 w-3 ${isValid ? 'text-(--color-surprise)' : 'text-(--color-danger)'}`}
|
||||
/>
|
||||
<span
|
||||
data-testid="drop-indicator-on"
|
||||
data-valid={isValid}
|
||||
data-drop-position={target.dropPosition}
|
||||
className="flex items-center"
|
||||
>
|
||||
<Icon
|
||||
icon="turn-down"
|
||||
className={`ml-2 h-3 w-3 ${isValid ? 'text-(--color-surprise)' : 'text-(--color-danger)'}`}
|
||||
/>
|
||||
</span>
|
||||
</DropIndicator>
|
||||
);
|
||||
}
|
||||
@@ -557,6 +564,7 @@ function SidebarDropIndicator({
|
||||
<span
|
||||
data-testid="drop-indicator-folder-name"
|
||||
data-valid={isValid}
|
||||
data-drop-position={target.dropPosition}
|
||||
className={`absolute -top-2.5 left-0 z-10 flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] leading-none whitespace-nowrap ${
|
||||
isValid
|
||||
? 'bg-(--color-surprise) text-(--color-font-surprise)'
|
||||
@@ -570,6 +578,7 @@ function SidebarDropIndicator({
|
||||
<span
|
||||
data-testid="drop-indicator-dot"
|
||||
data-valid={isValid}
|
||||
data-drop-position={target.dropPosition}
|
||||
className={`absolute -top-0.75 -left-0.75 block h-1.75 w-1.75 rounded-full ${
|
||||
isValid ? 'bg-(--color-surprise)' : 'bg-(--color-danger)'
|
||||
}`}
|
||||
|
||||
@@ -635,7 +635,7 @@ export const SpecView = ({
|
||||
|
||||
const specPaneToolbar = apiSpec?.contents ? (
|
||||
<div className="flex h-10 shrink-0 items-center gap-2 overflow-hidden border-b border-solid border-(--hl-md) px-(--padding-sm)">
|
||||
<span className="truncate text-sm text-(--hl) italic">
|
||||
<span data-testid="spec-openapi-version" className="truncate text-sm text-(--hl) italic">
|
||||
{parsedSpec?.openapi ? `OpenAPI ${parsedSpec.openapi}` : ''}
|
||||
</span>
|
||||
<span className="flex-1" />
|
||||
|
||||
Reference in new issue
Block a user