diff --git a/src/common/API/storageAPI.tsx b/src/common/API/storageAPI.tsx index 20f7664eb..151387634 100644 --- a/src/common/API/storageAPI.tsx +++ b/src/common/API/storageAPI.tsx @@ -11,6 +11,7 @@ const fetchCsrfToken = async (documentStorageURL: string): Promise => { method: "get", url: url, withCredentials: true, + headers: getHeaders(), }); const csrfToken = response.data.csrfToken; @@ -49,7 +50,7 @@ export const getQueueNumber = async (documentStorageURL: string): Promise issue > verify flow for Transferable Documen return; } + // console.log("🚀 Starting Magic Link integration test", getLocation()); + // console.log(`📧 Using inbox: ${MAILSLURP_INDEX_ID}`); + // create email address for a test user + // console.log("📬 Fetching test inbox..."); const inbox = await mailslurp.getInbox(MAILSLURP_INDEX_ID); + // console.log(`📧 Test email: ${inbox.emailAddress}`); + + const magicLinkConnect = async () => { + // Step 1: Navigate to creator page + await navigateToCreator(); + + // Step 2: Preview "Bill of Lading" form + await t.click(billOfLadingTitle); + await t.expect(previewOverlay.exists).ok("Preview overlay should be visible"); + + // Step 3: Create document + await t.click(createDocumentButton); + + // Step 4: Connect to Blockchain Wallet: Magiclink + await t.expect(connectBlockchainModal.exists).ok("Connect to Blockchain Wallet modal should appear"); + await t.click(Selector('[data-testid="connect-magic-header"]')); + await t.expect(connectToMagicLink.exists).ok("Connect to MagicLink should appear"); + await t.click(connectToMagicLink); + + // Step 5: Sign in to Magic + // console.log("🔐 Initiating Magic Link sign-in..."); + await t.wait(2000); // Increased wait for iframe loading + + await validateMagicIframeSelector(Selector("p").withText("Sign in to")); + await clickMagicIframeButton(Selector('button[aria-label="Email"]')); + await t.wait(3000); // Wait for email input form to load + + // Step 6: Enter email address + // console.log(`📧 Entering email: ${inbox.emailAddress}`); + await inputMagicIframeTexts(emailInput, inbox.emailAddress); + await clickMagicIframeButton(signInButton); + // console.log("✉️ Email submitted, waiting for verification..."); + }; + + await magicLinkConnect(); + + // console.log("⏳ Waiting for Magic Link response..."); + await t.wait(5000); // Increased wait for Magic processing + + // Check what Magic is showing + const deviceRegistrationText = Selector("h4").withText(/Please register this device to continue/); + + if (await deviceRegistrationText.exists) { + console.log("🔐 Device registration required - waiting for registration email..."); + // Switch to iframe to check what screen we're on + await t.switchToIframe(Selector(".magic-iframe")); + try { + // Wait for device registration email with longer timeout for CI + const registrationEmail = await mailslurp.waitForLatestEmail(inbox.id, 60000, true); + console.log("📧 Registration email received"); + + // Extract the registration link from the email + const registrationLinkMatch = /https:\/\/[^\s<>"]+/.exec(registrationEmail!.body!); + const registrationLink = registrationLinkMatch?.[0]; + + if (!registrationLink) { + throw new Error("Registration link not found in email"); + } + + console.log("🔗 Navigating to registration link..."); + await t.switchToMainWindow(); + await t.navigateTo(registrationLink); + await t.wait(5000); // Increased wait for page load + + const approveButton = Selector("button").withText("Approve"); + await t.expect(approveButton.exists).ok("Approve button should be visible"); + await t.click(approveButton); + console.log("✅ Device registration approved"); + + await t.wait(2000); + } catch (error) { + console.error("❌ Device registration failed:", error); + throw error; + } + // Step 1: Navigate to creator page + await t.navigateTo(`${location}`); + + await magicLinkConnect(); + } - // Step 1: Navigate to creator page - await navigateToCreator(); - - // Step 2: Preview "Bill of Lading" form - await t.click(billOfLadingTitle); - await t.expect(previewOverlay.exists).ok("Preview overlay should be visible"); - - // Step 3: Create document - await t.click(createDocumentButton); - - // Step 4: Connect to Blockchain Wallet: Magiclink - await t.expect(connectBlockchainModal.exists).ok("Connect to Blockchain Wallet modal should appear"); - await t.click(Selector('[data-testid="connect-magic-header"]')); - await t.expect(connectToMagicLink.exists).ok("Connect to MagicLink should appear"); - await t.click(connectToMagicLink); - - // Step 5: Sign in to Magic - await t.wait(1000); - await validateMagicIframeSelector(Selector("p").withText("Sign in to")); - await inputMagicIframeTexts(emailInput, inbox.emailAddress); - await clickMagicIframeButton(signInButton); - - // wait for verification code to arrive to email then extract code + // console.log("📧 Waiting for verification code email..."); + // wait for verification code to arrive to email then extract code with longer timeout for CI const email = await mailslurp.waitForLatestEmail(inbox.id, 30000, true); + // console.log("📧 Verification email received"); // use regex to extract the confirmation code which is 6 digits const code = /[^#]([0-9]{6})/.exec(email!.body!)?.[1]; + if (!code) { + console.error("❌ Failed to extract verification code from email:", email.body); + throw new Error("Verification code not found in email"); + } + + // console.log(`🔢 Extracted verification code: ${code}`); + // Step 6: Enter verification code - await t.wait(1000); + // console.log("🔢 Entering verification code..."); + await t.wait(2000); // Wait for code input form to load await validateMagicIframeSelector(Selector("h4").withText(/Please enter the code sent to/)); + // console.log("🔢 Validating iframe code input..."); await inputMagicIframeTexts(codeInput, code!); - await t.wait(5000); + // console.log("✅ Verification code entered, waiting for validation..."); + await t.wait(2000); // Increased wait for code validation // Step 7: Get wallet address + // console.log("💰 Retrieving wallet address..."); await t.expect(walletAddressDiv.exists).ok("Wallet address should be visible"); const walletAddress = await walletAddressDiv.innerText; + // console.log(`💰 Wallet address: ${walletAddress}`); // Step 8: Transfer funds to wallet - const wallet = new ethers.Wallet("0xe82294532bcfcd8e0763ee5cef194f36f00396be59b94fb418f5f8d83140d9a7"); - const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); - const signer = wallet.connect(provider); - const balance = await signer.getBalance(); - if (!balance.gt(BigNumber.from("10000000000000000000"))) { - // 10 ethers - throw new Error("Insufficient balance"); + // console.log("💸 Transferring funds to Magic wallet..."); + try { + const wallet = new ethers.Wallet("0xe82294532bcfcd8e0763ee5cef194f36f00396be59b94fb418f5f8d83140d9a7"); + const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); + const signer = wallet.connect(provider); + + const balance = await signer.getBalance(); + // console.log(`💰 Funder wallet balance: ${ethers.utils.formatEther(balance)} ETH`); + + if (!balance.gt(BigNumber.from("10000000000000000000"))) { + throw new Error(`Insufficient balance: ${ethers.utils.formatEther(balance)} ETH`); + } + + const tx = await signer.sendTransaction({ + to: walletAddress, + value: BigNumber.from("10000000000000000000"), // 10 ethers + }); + + // console.log(`🔗 Transaction hash: ${tx.hash}`); + await tx.wait(); + // console.log(`✅ Transaction confirmed in block: ${receipt.blockNumber}`); + + // Clean up email + await mailslurp.deleteEmail(email.id); + // console.log("🗑️ Verification email deleted"); + } catch (error) { + // console.error("❌ Fund transfer failed:", error); + throw error; } - const tx = await signer.sendTransaction({ - to: walletAddress, - value: BigNumber.from("10000000000000000000"), // 10 ethers - }); - await tx.wait(); - await mailslurp.deleteEmail(email.id); // Step 9: Network Selector + // console.log(" 🌐 Selecting network..."); await t.expect(networkSelector.exists).ok("Network selector should appear"); await t.click(continueConnectBlockchainModal); @@ -154,6 +247,7 @@ test("should complete full create > issue > verify flow for Transferable Documen await t.click(formNextButton); await t.expect(getLocation()).contains("/creator/publish", "Should navigate to publish page"); await t.expect(processTitle.exists).ok("Issuance success title should be visible"); + await t.wait(5000); await t.expect(processTitle.innerText).eql("Document issued successfully"); // Step 15: Download issued document