mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
test: add timeout on keys page
This commit is contained in:
parent
8faa7dbc39
commit
3ad108cb63
1 changed files with 121 additions and 69 deletions
|
|
@ -13,84 +13,123 @@ test.describe("Invite User, Set Password, and Login", () => {
|
|||
await loginToUI(page); // Login as admin first
|
||||
await page.goto("http://localhost:4000/ui?page=teams");
|
||||
|
||||
// --- Create Team 1 ---
|
||||
await page.getByRole('button', { name: '+ Create New Team' }).click();
|
||||
await page.getByLabel('Team Name').waitFor({ state: 'visible', timeout: 5000 }); // Wait for label
|
||||
await page.getByLabel('Team Name').click();
|
||||
await page.getByLabel('Team Name').fill(teamName1);
|
||||
await page.getByRole('button', { name: 'Create Team' }).click();
|
||||
// Wait for the modal to close or for a success message if applicable
|
||||
await expect(page.locator('.ant-modal-wrap').filter({ hasText: 'Create New Team' })).not.toBeVisible({ timeout: 10000 });
|
||||
console.log(`Created Team 1: ${teamName1}`);
|
||||
|
||||
// --- Create Team 2 ---
|
||||
await page.getByRole('button', { name: '+ Create New Team' }).click();
|
||||
await page.getByLabel('Team Name').waitFor({ state: 'visible', timeout: 5000 }); // Wait for label
|
||||
await page.getByLabel('Team Name').click();
|
||||
await page.getByLabel('Team Name').fill(teamName2);
|
||||
await page.getByRole('button', { name: 'Create Team' }).click();
|
||||
// Wait for the modal to close or for a success message if applicable
|
||||
await expect(page.locator('.ant-modal-wrap').filter({ hasText: 'Create New Team' })).not.toBeVisible({ timeout: 10000 });
|
||||
console.log(`Created Team 2: ${teamName2}`);
|
||||
|
||||
// Verify both teams are listed
|
||||
await page.goto("http://localhost:4000/ui?page=teams"); // Refresh or ensure on teams page
|
||||
await expect(page.getByText(teamName1)).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.getByText(teamName2)).toBeVisible({ timeout: 10000 });
|
||||
// --- Create Team 1 ---
|
||||
await page.getByRole("button", { name: "+ Create New Team" }).click();
|
||||
await page
|
||||
.getByLabel("Team Name")
|
||||
.waitFor({ state: "visible", timeout: 5000 }); // Wait for label
|
||||
await page.getByLabel("Team Name").click();
|
||||
await page.getByLabel("Team Name").fill(teamName1);
|
||||
await page.getByRole("button", { name: "Create Team" }).click();
|
||||
// Wait for the modal to close or for a success message if applicable
|
||||
await expect(
|
||||
page.locator(".ant-modal-wrap").filter({ hasText: "Create New Team" })
|
||||
).not.toBeVisible({ timeout: 10000 });
|
||||
console.log(`Created Team 1: ${teamName1}`);
|
||||
|
||||
// --- Create Team 2 ---
|
||||
await page.getByRole("button", { name: "+ Create New Team" }).click();
|
||||
await page
|
||||
.getByLabel("Team Name")
|
||||
.waitFor({ state: "visible", timeout: 5000 }); // Wait for label
|
||||
await page.getByLabel("Team Name").click();
|
||||
await page.getByLabel("Team Name").fill(teamName2);
|
||||
await page.getByRole("button", { name: "Create Team" }).click();
|
||||
// Wait for the modal to close or for a success message if applicable
|
||||
await expect(
|
||||
page.locator(".ant-modal-wrap").filter({ hasText: "Create New Team" })
|
||||
).not.toBeVisible({ timeout: 10000 });
|
||||
console.log(`Created Team 2: ${teamName2}`);
|
||||
|
||||
// Verify both teams are listed
|
||||
await page.goto("http://localhost:4000/ui?page=teams"); // Refresh or ensure on teams page
|
||||
await expect(page.getByText(teamName1)).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.getByText(teamName2)).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// --- Navigate to Keys Page ---
|
||||
await page.goto("http://localhost:4000/ui?page=api-keys");
|
||||
await expect(page.getByRole('button', { name: '+ Create New Key' })).toBeVisible(); // Wait for page load
|
||||
await page.waitForTimeout(30000);
|
||||
await expect(
|
||||
page.getByRole("button", { name: "+ Create New Key" })
|
||||
).toBeVisible(); // Wait for page load
|
||||
|
||||
// --- Create Key for Team 1 ---
|
||||
await page.getByRole('button', { name: '+ Create New Key' }).click();
|
||||
const createKeyModal1 = page.locator('.ant-modal-wrap').filter({ hasText: 'Key Ownership' });
|
||||
await page.getByRole("button", { name: "+ Create New Key" }).click();
|
||||
const createKeyModal1 = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Key Ownership" });
|
||||
await expect(createKeyModal1).toBeVisible();
|
||||
|
||||
// Select Team 1
|
||||
await createKeyModal1.locator('.ant-select-selector >> input').first().click(); // Click to open team dropdown
|
||||
await page.locator('.ant-select-item-option').filter({ hasText: teamName1 }).click(); // Click specific team name
|
||||
await createKeyModal1
|
||||
.locator(".ant-select-selector >> input")
|
||||
.first()
|
||||
.click(); // Click to open team dropdown
|
||||
await page
|
||||
.locator(".ant-select-item-option")
|
||||
.filter({ hasText: teamName1 })
|
||||
.click(); // Click specific team name
|
||||
|
||||
// Enter Key Name 1
|
||||
await page.fill('input[id="key_alias"]', keyName1);
|
||||
|
||||
// Click on models dropdown
|
||||
await page.locator('input#models').click();
|
||||
await page.waitForSelector('.ant-select-item-option[title="All Team Models"]');
|
||||
await page.locator('.ant-select-item-option[title="All Team Models"]').click();
|
||||
await page.locator("input#models").click();
|
||||
await page.waitForSelector(
|
||||
'.ant-select-item-option[title="All Team Models"]'
|
||||
);
|
||||
await page
|
||||
.locator('.ant-select-item-option[title="All Team Models"]')
|
||||
.click();
|
||||
|
||||
// Click Create Key
|
||||
await createKeyModal1.getByRole('button', { name: 'Create Key' }).click();
|
||||
await createKeyModal1.getByRole("button", { name: "Create Key" }).click();
|
||||
|
||||
// Close the Key Generated modal (which appears after successful creation)
|
||||
const keyGeneratedModal1 = page.locator('.ant-modal-wrap').filter({ hasText: 'Save your Key' });
|
||||
const keyGeneratedModal1 = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Save your Key" });
|
||||
await expect(keyGeneratedModal1).toBeVisible({ timeout: 10000 });
|
||||
await keyGeneratedModal1.locator('button[aria-label="Close"]').click();
|
||||
await expect(keyGeneratedModal1).not.toBeVisible(); // Wait for close
|
||||
console.log(`Created Key 1: ${keyName1} for Team: ${teamName1}`);
|
||||
|
||||
// --- Create Key for Team 2 ---
|
||||
await page.getByRole('button', { name: '+ Create New Key' }).click();
|
||||
const createKeyModal2 = page.locator('.ant-modal-wrap').filter({ hasText: 'Key Ownership' });
|
||||
await page.getByRole("button", { name: "+ Create New Key" }).click();
|
||||
const createKeyModal2 = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Key Ownership" });
|
||||
await expect(createKeyModal2).toBeVisible();
|
||||
|
||||
// Select Team 2
|
||||
await createKeyModal2.locator('.ant-select-selector >> input').first().click(); // Click to open team dropdown
|
||||
await page.locator('.ant-select-item-option').filter({ hasText: teamName2 }).click(); // Click specific team name
|
||||
await createKeyModal2
|
||||
.locator(".ant-select-selector >> input")
|
||||
.first()
|
||||
.click(); // Click to open team dropdown
|
||||
await page
|
||||
.locator(".ant-select-item-option")
|
||||
.filter({ hasText: teamName2 })
|
||||
.click(); // Click specific team name
|
||||
|
||||
// Enter Key Name 2
|
||||
await page.fill('input[id="key_alias"]', keyName2);
|
||||
|
||||
// Click on models dropdown
|
||||
await page.locator('input#models').click();
|
||||
await page.waitForSelector('.ant-select-item-option[title="All Team Models"]');
|
||||
await page.locator('.ant-select-item-option[title="All Team Models"]').click();
|
||||
await page.locator("input#models").click();
|
||||
await page.waitForSelector(
|
||||
'.ant-select-item-option[title="All Team Models"]'
|
||||
);
|
||||
await page
|
||||
.locator('.ant-select-item-option[title="All Team Models"]')
|
||||
.click();
|
||||
|
||||
// Click Create Key
|
||||
await createKeyModal2.getByRole('button', { name: 'Create Key' }).click();
|
||||
await createKeyModal2.getByRole("button", { name: "Create Key" }).click();
|
||||
|
||||
// Close the Key Generated modal
|
||||
const keyGeneratedModal2 = page.locator('.ant-modal-wrap').filter({ hasText: 'Save your Key' });
|
||||
const keyGeneratedModal2 = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Save your Key" });
|
||||
await expect(keyGeneratedModal2).toBeVisible({ timeout: 10000 });
|
||||
await keyGeneratedModal2.locator('button[aria-label="Close"]').click();
|
||||
await expect(keyGeneratedModal2).not.toBeVisible(); // Wait for close
|
||||
|
|
@ -109,72 +148,86 @@ test.describe("Invite User, Set Password, and Login", () => {
|
|||
await internalUserTab.click();
|
||||
|
||||
// --- Invite User Flow ---
|
||||
await page.getByRole('button', { name: '+ Invite User' }).click();
|
||||
await page.getByRole("button", { name: "+ Invite User" }).click();
|
||||
|
||||
// Wait for the invite user modal to be visible
|
||||
const inviteModal = page.locator('.ant-modal-wrap').filter({ hasText: 'Invite User' });
|
||||
const inviteModal = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Invite User" });
|
||||
await expect(inviteModal).toBeVisible();
|
||||
|
||||
testEmail = `test-${Date.now()}@litellm.ai`; // Use a unique email
|
||||
// Assuming the email input is the first one with 'base-input' test id inside the modal
|
||||
await inviteModal.getByTestId('base-input').first().fill(testEmail);
|
||||
await inviteModal.getByTestId("base-input").first().fill(testEmail);
|
||||
|
||||
// Select Global Admin Role (or another appropriate role)
|
||||
const globalRoleLabel = inviteModal.getByLabel('Global Proxy Role');
|
||||
const globalRoleLabel = inviteModal.getByLabel("Global Proxy Role");
|
||||
await globalRoleLabel.click();
|
||||
// Wait for the dropdown option to be visible before clicking
|
||||
const adminRoleOption = page.getByTitle('Admin (All Permissions)', { exact: true });
|
||||
await adminRoleOption.waitFor({ state: 'visible', timeout: 5000 });
|
||||
const adminRoleOption = page.getByTitle("Admin (All Permissions)", {
|
||||
exact: true,
|
||||
});
|
||||
await adminRoleOption.waitFor({ state: "visible", timeout: 5000 });
|
||||
await adminRoleOption.click();
|
||||
|
||||
// Select Team - Add explicit wait before clicking
|
||||
const teamIdLabel = inviteModal.getByLabel('Team ID');
|
||||
const teamIdLabel = inviteModal.getByLabel("Team ID");
|
||||
// Wait for the label associated with the Team ID select to be visible
|
||||
await teamIdLabel.waitFor({ state: 'visible', timeout: 10000 }); // Increased timeout for safety
|
||||
await teamIdLabel.waitFor({ state: "visible", timeout: 10000 }); // Increased timeout for safety
|
||||
await teamIdLabel.click();
|
||||
|
||||
// Wait for the team name option to be visible in the dropdown
|
||||
const teamNameOption = page.getByText(teamName1, { exact: true });
|
||||
await teamNameOption.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await teamNameOption.waitFor({ state: "visible", timeout: 5000 });
|
||||
await teamNameOption.click();
|
||||
|
||||
// Create User
|
||||
await inviteModal.getByRole('button', { name: 'Create User' }).click();
|
||||
await inviteModal.getByRole("button", { name: "Create User" }).click();
|
||||
|
||||
// --- Capture Invitation Link ---
|
||||
const invitationModal = page.locator('.ant-modal-wrap').filter({ hasText: 'Invitation Link' });
|
||||
const invitationModal = page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Invitation Link" });
|
||||
await expect(invitationModal).toBeVisible({ timeout: 15000 }); // Wait longer for modal
|
||||
|
||||
// Locate the text element containing the URL more reliably
|
||||
const invitationUrl = await page
|
||||
.locator('div.flex.justify-between.pt-5.pb-2') // find the correct div
|
||||
.filter({ hasText: 'Invitation Link' }) // find the div that has text "Invitation Link"
|
||||
.locator('p') // find all <p> inside that div
|
||||
.nth(1) // pick the second <p> (index 1)
|
||||
.innerText();
|
||||
.locator("div.flex.justify-between.pt-5.pb-2") // find the correct div
|
||||
.filter({ hasText: "Invitation Link" }) // find the div that has text "Invitation Link"
|
||||
.locator("p") // find all <p> inside that div
|
||||
.nth(1) // pick the second <p> (index 1)
|
||||
.innerText();
|
||||
|
||||
// Close Invitation Link Modal
|
||||
await page.locator('.ant-modal-wrap').filter({ hasText: 'Invitation Link' }).locator('button[aria-label="Close"]').click();
|
||||
await page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Invitation Link" })
|
||||
.locator('button[aria-label="Close"]')
|
||||
.click();
|
||||
|
||||
// Close Invite User Modal
|
||||
await page.locator('.ant-modal-wrap').filter({ hasText: 'Invite User' }).locator('button[aria-label="Close"]').click();
|
||||
await page
|
||||
.locator(".ant-modal-wrap")
|
||||
.filter({ hasText: "Invite User" })
|
||||
.locator('button[aria-label="Close"]')
|
||||
.click();
|
||||
|
||||
// Open invite link as new page (simulate invited user)
|
||||
const context = await page.context()?.browser()?.newContext();
|
||||
const invitedUserPage = await context?.newPage();
|
||||
if (!invitedUserPage) {
|
||||
throw new Error('invitedUserPage is undefined');
|
||||
throw new Error("invitedUserPage is undefined");
|
||||
}
|
||||
await invitedUserPage?.goto(invitationUrl || '');
|
||||
await invitedUserPage?.goto(invitationUrl || "");
|
||||
|
||||
//Insert new password
|
||||
await invitedUserPage?.fill('input#password', testPassword);
|
||||
await invitedUserPage?.fill("input#password", testPassword);
|
||||
|
||||
//Click on submit
|
||||
await invitedUserPage?.getByRole('button', { name: 'Sign Up' }).click();
|
||||
await invitedUserPage?.getByRole("button", { name: "Sign Up" }).click();
|
||||
|
||||
// // --- Verify Keys Created ---
|
||||
// await invitedUserPage?.waitForSelector("table");
|
||||
// await invitedUserPage?.waitForSelector("table");
|
||||
|
||||
// // Verify keyName1 (associated with user's team) IS visible in the table
|
||||
// const keyTable = invitedUserPage.locator('table'); // Locate the table element
|
||||
|
|
@ -186,6 +239,5 @@ test.describe("Invite User, Set Password, and Login", () => {
|
|||
// // Verify keyName2 (associated with the *other* team) IS NOT visible
|
||||
// await expect(keyTable.getByText(keyName2, { exact: true })).not.toBeVisible();
|
||||
// console.log(`Verified key ${keyName2} is NOT visible for user ${testEmail}`);
|
||||
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue