Fix ConfirmationButton usage in pricing page and e2e tests
- Update pricing page to use ConfirmationButton API correctly (isConfirming, onConfirm, onCancel, onActionClick) - Fix e2e tests to set up response listeners before navigation - Fix validation error selector to use .first() for multiple matches - All 9 e2e tests now passing
This commit is contained in:
parent
1874c3a057
commit
1ef5ebe493
2 changed files with 64 additions and 38 deletions
|
|
@ -49,6 +49,7 @@ export default function AdminPricingPage() {
|
|||
const [errors, setErrors] = useState<ValidationErrors>({});
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [success, setSuccess] = useState(false);
|
||||
const [isConfirming, setIsConfirming] = useState(false);
|
||||
|
||||
const fetchConfig = useCallback(async () => {
|
||||
setError(null);
|
||||
|
|
@ -180,12 +181,16 @@ export default function AdminPricingPage() {
|
|||
},
|
||||
});
|
||||
|
||||
const handleSave = () => {
|
||||
if (!formData) return;
|
||||
const handleConfirmSave = () => {
|
||||
if (!formData) {
|
||||
setIsConfirming(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const validationErrors = validateForm(formData);
|
||||
if (Object.keys(validationErrors).length > 0) {
|
||||
setErrors(validationErrors);
|
||||
setIsConfirming(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -199,6 +204,7 @@ export default function AdminPricingPage() {
|
|||
eur_min_sell: formData.eur_min_sell,
|
||||
eur_max_sell: formData.eur_max_sell,
|
||||
});
|
||||
setIsConfirming(false);
|
||||
};
|
||||
|
||||
if (isLoading || !formData) {
|
||||
|
|
@ -385,16 +391,19 @@ export default function AdminPricingPage() {
|
|||
|
||||
<div style={formStyles.actions}>
|
||||
<ConfirmationButton
|
||||
onClick={handleSave}
|
||||
disabled={hasErrors || isSaving}
|
||||
confirmMessage={t("pricing.confirmSave")}
|
||||
style={{
|
||||
isConfirming={isConfirming}
|
||||
onConfirm={handleConfirmSave}
|
||||
onCancel={() => setIsConfirming(false)}
|
||||
onActionClick={() => setIsConfirming(true)}
|
||||
actionLabel={isSaving ? tCommon("saving") : t("pricing.save")}
|
||||
confirmLabel={tCommon("confirm")}
|
||||
cancelLabel={tCommon("cancel")}
|
||||
isLoading={isSaving}
|
||||
actionButtonStyle={{
|
||||
...buttonStyles.primary,
|
||||
...(hasErrors || isSaving ? buttonStyles.disabled : {}),
|
||||
}}
|
||||
>
|
||||
{isSaving ? tCommon("saving") : t("pricing.save")}
|
||||
</ConfirmationButton>
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,16 +24,18 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
await expect(pricingLink).toBeVisible();
|
||||
|
||||
// Test page access and structure
|
||||
// Set up response listener before navigation
|
||||
const responsePromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await page.goto("/admin/pricing");
|
||||
await expect(page).toHaveURL("/admin/pricing");
|
||||
|
||||
// Wait for API call to complete and form to render
|
||||
await page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
await responsePromise;
|
||||
// Wait for form inputs to be visible (indicates form has loaded)
|
||||
await expect(page.locator('input[type="number"]').first()).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible();
|
||||
await expect(page.getByText("Configure premium pricing and trade amount limits")).toBeVisible();
|
||||
|
||||
// Check all form fields are present (using text + input selector since labels aren't associated)
|
||||
|
|
@ -52,12 +54,14 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
});
|
||||
|
||||
test("can view current pricing configuration", async ({ page }) => {
|
||||
// Set up response listener before navigation
|
||||
const responsePromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await page.goto("/admin/pricing");
|
||||
|
||||
// Wait for API call to complete and form to render
|
||||
await page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await responsePromise;
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
|
@ -77,12 +81,14 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
});
|
||||
|
||||
test("can update pricing configuration", async ({ page }) => {
|
||||
// Set up response listener before navigation
|
||||
const responsePromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await page.goto("/admin/pricing");
|
||||
|
||||
// Wait for API call to complete and form to render
|
||||
await page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await responsePromise;
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
|
@ -98,6 +104,13 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
await premiumBuyInput.clear();
|
||||
await premiumBuyInput.fill(newBuyValue);
|
||||
|
||||
// Wait a bit for any validation to clear
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// Verify save button is enabled before clicking
|
||||
const saveButton = page.getByRole("button", { name: /Save Changes/i });
|
||||
await expect(saveButton).toBeEnabled({ timeout: 5000 });
|
||||
|
||||
// Set up response listener before clicking save
|
||||
const putPromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "PUT"
|
||||
|
|
@ -106,12 +119,12 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
|
||||
// Click save button (with confirmation)
|
||||
await page.getByRole("button", { name: /Save Changes/i }).click();
|
||||
// Click save button (enters confirmation mode)
|
||||
await saveButton.click();
|
||||
|
||||
// Confirm the save action
|
||||
await expect(page.getByText(/Are you sure/i)).toBeVisible();
|
||||
await page.getByRole("button", { name: /confirm|yes|ok/i }).click();
|
||||
// Confirm the save action (button text changes to "Confirm")
|
||||
await expect(page.getByRole("button", { name: /Confirm/i })).toBeVisible({ timeout: 5000 });
|
||||
await page.getByRole("button", { name: /Confirm/i }).click();
|
||||
|
||||
// Wait for API calls to complete
|
||||
await putPromise;
|
||||
|
|
@ -127,12 +140,14 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
});
|
||||
|
||||
test("validation prevents invalid values", async ({ page }) => {
|
||||
// Set up response listener before navigation
|
||||
const responsePromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await page.goto("/admin/pricing");
|
||||
|
||||
// Wait for API call to complete and form to render
|
||||
await page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await responsePromise;
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
|
@ -146,8 +161,8 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
|
||||
// Try to save
|
||||
await page.getByRole("button", { name: /Save Changes/i }).click();
|
||||
await expect(page.getByText(/confirm|yes|ok/i)).toBeVisible();
|
||||
await page.getByRole("button", { name: /confirm|yes|ok/i }).click();
|
||||
await expect(page.getByRole("button", { name: /Confirm/i })).toBeVisible({ timeout: 2000 });
|
||||
await page.getByRole("button", { name: /Confirm/i }).click();
|
||||
|
||||
// Should show validation error
|
||||
await expect(page.getByText(/must be between.*-100.*100/i)).toBeVisible({ timeout: 2000 });
|
||||
|
|
@ -167,22 +182,24 @@ test.describe("Admin Pricing Page - Admin Access", () => {
|
|||
|
||||
// Try to save
|
||||
await page.getByRole("button", { name: /Save Changes/i }).click();
|
||||
await expect(page.getByText(/confirm|yes|ok/i)).toBeVisible();
|
||||
await page.getByRole("button", { name: /confirm|yes|ok/i }).click();
|
||||
await expect(page.getByRole("button", { name: /Confirm/i })).toBeVisible({ timeout: 2000 });
|
||||
await page.getByRole("button", { name: /Confirm/i }).click();
|
||||
|
||||
// Should show validation error
|
||||
await expect(page.getByText(/minimum must be less than maximum/i)).toBeVisible({
|
||||
// Should show validation error (there are two - one for min, one for max)
|
||||
await expect(page.getByText(/minimum must be less than maximum/i).first()).toBeVisible({
|
||||
timeout: 2000,
|
||||
});
|
||||
});
|
||||
|
||||
test("form fields update correctly when values change", async ({ page }) => {
|
||||
// Set up response listener before navigation
|
||||
const responsePromise = page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await page.goto("/admin/pricing");
|
||||
|
||||
// Wait for API call to complete and form to render
|
||||
await page.waitForResponse(
|
||||
(resp) => resp.url().includes("/api/admin/pricing") && resp.request().method() === "GET"
|
||||
);
|
||||
await responsePromise;
|
||||
await expect(page.getByRole("heading", { name: "Pricing Configuration" })).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue