diff --git a/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx b/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx new file mode 100644 index 00000000..166f66ad --- /dev/null +++ b/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx @@ -0,0 +1,39 @@ +function TransactionLoader({ showInProgress, showError, toggleToast }) { + return showInProgress || showError ? ( +
+
+
+ Just Now + {showError && ( + toggleToast(false)} + > + )} +
+
+ {showInProgress ? ( +
+ +
+ Processing your request ... +
+
+ ) : ( +
+ +
+ Something went wrong. Please try resubmitting the request. +
+
+ )} +
+
+
+ ) : null; +} +return { TransactionLoader }; diff --git a/instances/treasury-devdao.near/widget/components/VoteActions.jsx b/instances/treasury-devdao.near/widget/components/VoteActions.jsx index 1ecaadcc..1f35290c 100644 --- a/instances/treasury-devdao.near/widget/components/VoteActions.jsx +++ b/instances/treasury-devdao.near/widget/components/VoteActions.jsx @@ -4,6 +4,9 @@ if (!instance) { } const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`); +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const votes = props.votes ?? {}; const proposalId = props.proposalId; @@ -37,6 +40,7 @@ const [isInsufficientBalance, setInsufficientBal] = useState(false); const [showWarning, setShowWarning] = useState(false); const [isReadyToBeWithdrawn, setIsReadyToBeWithdrawn] = useState(true); const [showConfirmModal, setConfirmModal] = useState(null); +const [showErrorToast, setShowErrorToast] = useState(false); useEffect(() => { if (!avoidCheckForBalance) { @@ -74,20 +78,36 @@ function getProposalData() { (result) => result ); } - useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForVoteOnProposal = () => { getProposalData().then((proposal) => { if (JSON.stringify(proposal.votes) !== JSON.stringify(votes)) { checkProposalStatus(); + clearTimeout(errorTimeout); setTxnCreated(false); } else { - setTimeout(() => checkForVoteOnProposal(), 1000); + checkTxnTimeout = setTimeout(checkForVoteOnProposal, 1000); } }); }; + checkForVoteOnProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -134,7 +154,10 @@ const InsufficientBalanceWarning = () => {
Just Now - setShowWarning(false)}> + setShowWarning(false)} + >
The request cannot be approved because the treasury balance is @@ -144,8 +167,15 @@ const InsufficientBalanceWarning = () => {
) : null; }; + return ( + setShowErrorToast(false)} + /> + {} }; +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; + const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url") || { href: () => {}, }; @@ -45,6 +49,7 @@ const [selectedTokensAvailable, setSelectedTokensAvailable] = useState(null); const [isReceiverRegistered, setReceiverRegister] = useState(false); const [isLoadingProposals, setLoadingProposals] = useState(false); const [showCancelModal, setShowCancelModal] = useState(false); +const [showErrorToast, setShowErrorToast] = useState(false); useEffect(() => { if (!showProposalSelection) { @@ -150,19 +155,36 @@ function cleanInputs() { // close canvas after proposal is submitted useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { cleanInputs(); onCloseCanvas(); + clearTimeout(errorTimeout); refreshData(); setTxnCreated(false); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; + checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -373,6 +395,11 @@ useEffect(() => { return ( + setShowErrorToast(false)} + /> { } return (
- {content} -
- {showToastStatus !== "InProgress" && showToastStatus !== "Removed" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -205,7 +213,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx b/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx index 234c2ea1..37d72e5f 100644 --- a/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx +++ b/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx @@ -150,26 +150,34 @@ const ToastStatusContent = () => { } return (
- {content} -
- {showToastStatus !== "InProgress" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -182,7 +190,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx b/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx index 8e7a0192..578ebd02 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx @@ -1,6 +1,9 @@ const { encodeToMarkdown } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common" ); +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const instance = props.instance; if (!instance) { @@ -21,6 +24,7 @@ const onRefresh = props.onRefresh; const [isTxnCreated, setTxnCreated] = useState(false); const [lastProposalId, setLastProposalId] = useState(null); +const [showErrorToast, setShowErrorToast] = useState(false); function getLastProposalId() { return Near.asyncView(treasuryDaoID, "get_last_proposal_id").then( @@ -35,17 +39,33 @@ useEffect(() => { // show toast after proposal is submitted useEffect(() => { if (isTxnCreated && typeof onRefresh === "function") { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { setToastStatus(true); setTxnCreated(false); + clearTimeout(errorTimeout); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated, onRefresh]); @@ -205,6 +225,13 @@ const NoButton = styled.button` return ( <> + {onRefresh && ( + setShowErrorToast(false)} + /> + )}
@@ -248,17 +258,33 @@ useEffect(() => { useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { setToastStatus(true); setTxnCreated(false); + clearTimeout(errorTimeout); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -318,6 +344,11 @@ useEffect(() => { return ( + setShowErrorToast(false)} + />
Theme & Logo
{!metadata ? ( @@ -421,7 +452,7 @@ return ( label: "Save changes", onClick: onSubmitClick, loading: isTxnCreated, - disabled: !hasCreatePermission || error, + disabled: !hasCreatePermission || error || isTxnCreated, }} />
diff --git a/instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx b/instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx index f5edf8d8..1c52eafc 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx @@ -1,6 +1,9 @@ const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url") || { href: () => {}, }; +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const { encodeToMarkdown, hasPermission, getRoleWiseData } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common" @@ -37,6 +40,7 @@ const [valueError, setValueError] = useState(null); const [showConfirmModal, setConfirmModal] = useState(null); const [rolesData, setRolesData] = useState(null); const [refreshData, setRefreshData] = useState(false); +const [showErrorToast, setShowErrorToast] = useState(false); const hasCreatePermission = hasPermission( treasuryDaoID, @@ -87,16 +91,33 @@ useEffect(() => { useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { setToastStatus(true); + setTxnCreated(false); + clearTimeout(errorTimeout); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -238,22 +259,27 @@ const SubmitToast = () => {
Just Now setToastStatus(null)} >
-
Threshold change request submitted.
- - View it - +
+ +
+
Threshold change request submitted.
+ + View it + +
+
@@ -279,6 +305,11 @@ const requiredVotes = selectedGroup return ( + setShowErrorToast(false)} + /> {Array.isArray(rolesData) && rolesData.length ? (
setConfirmModal(true), loading: isTxnCreated, diff --git a/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx b/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx index 2c327340..5dc25d02 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx @@ -4,6 +4,9 @@ const { encodeToMarkdown, hasPermission, getRoleWiseData } = VM.require( encodeToMarkdown: () => {}, hasPermission: () => {}, }; +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url") || { href: () => {}, @@ -59,6 +62,7 @@ const [isSubmittingChangeRequest, setSubmittingChangeRequest] = useState(false); const [showAffectedProposalsModal, setShowAffectedProposalsModal] = useState(false); +const [showErrorToast, setShowErrorToast] = useState(false); const [showLoader, setLoading] = useState(false); const Container = styled.div` @@ -258,23 +262,34 @@ const submitChangeRequest = () => { }; useEffect(() => { - Near.asyncView(treasuryDaoID, "get_proposal", { - id: lastProposalId - 1, - }).then((proposal) => { - const proposal_period = - proposal?.kind?.ChangePolicyUpdateParameters?.parameters?.proposal_period; + if (isSubmittingChangeRequest) { + let errorTimeout = null; + Near.asyncView(treasuryDaoID, "get_proposal", { + id: lastProposalId - 1, + }).then((proposal) => { + const proposal_period = + proposal?.kind?.ChangePolicyUpdateParameters?.parameters + ?.proposal_period; - if ( - proposal_period && - isSubmittingChangeRequest && - Number(proposal_period.substring(0, proposal_period.length - 9)) / - (24 * 60 * 60) === - Number(durationDays) - ) { - setToastStatus(true); + if ( + proposal_period && + isSubmittingChangeRequest && + Number(proposal_period.substring(0, proposal_period.length - 9)) / + (24 * 60 * 60) === + Number(durationDays) + ) { + setToastStatus(true); + setSubmittingChangeRequest(false); + clearTimeout(errorTimeout); + } + }); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); setSubmittingChangeRequest(false); - } - }); + }, 20000); + } }, [isSubmittingChangeRequest, lastProposalId]); const changeDurationDays = (newDurationDays) => { @@ -286,6 +301,11 @@ const showImpactedRequests = return ( + setShowErrorToast(false)} + />
Voting Duration
@@ -461,9 +481,11 @@ return ( label: "Submit Request", loading: showLoader, disabled: - durationDays === currentDurationDays || + parseFloat(durationDays ? durationDays : 0) === + currentDurationDays || showLoader || - !hasCreatePermission, + !hasCreatePermission || + isSubmittingChangeRequest, onClick: submitChangeRequest, }} /> @@ -474,20 +496,28 @@ return (
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
-
Voting duration change request submitted.
- - View it - +
+ +
+
Voting duration change request submitted.
+ + View it + +
+
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx b/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx index c478447b..8f720c14 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx @@ -178,26 +178,34 @@ const ToastStatusContent = () => { } return (
- {content} -
- {showToastStatus !== "InProgress" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -210,7 +218,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx b/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx index 0d17da95..45e68ea7 100644 --- a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx +++ b/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx @@ -3,7 +3,9 @@ const { getNearBalances, LOCKUP_MIN_BALANCE_FOR_STORAGE, TooltipText } = const { NearToken } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons" ) || { NearToken: () => <> }; - +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const { encodeToMarkdown } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common" ); @@ -58,6 +60,7 @@ const [lockupStakedPoolsWithBalance, setLockupStakedPoolsWithBalance] = useState(null); const [lockupStakedPoolId, setLockupStakedPoolId] = useState(null); const [lockupAlreadyStaked, setLockupAlreadyStaked] = useState(false); +const [showErrorToast, setShowErrorToast] = useState(false); function formatNearAmount(amount) { return Big(amount ?? "0") @@ -127,19 +130,35 @@ function cleanInputs() { useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { cleanInputs(); onCloseCanvas(); refreshData(); + clearTimeout(errorTimeout); setTxnCreated(false); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -380,6 +399,11 @@ useEffect(() => { return ( + setShowErrorToast(false)} + /> <> }; + const { NearToken } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons" ) || { NearToken: () => <> }; @@ -62,6 +66,7 @@ const [lockupStakedPoolsWithBalance, setLockupStakedPoolsWithBalance] = const [showWarning, setShowWarning] = useState(false); const [lockupStakedPoolId, setLockupStakedPoolId] = useState(null); +const [showErrorToast, setShowErrorToast] = useState(false); function formatNearAmount(amount) { return Big(amount ?? "0") @@ -183,19 +188,35 @@ function cleanInputs() { useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { cleanInputs(); onCloseCanvas(); refreshData(); + clearTimeout(errorTimeout); setTxnCreated(false); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -387,6 +408,11 @@ useEffect(() => { return ( + setShowErrorToast(false)} + /> <> }; const instance = props.instance; const onCloseCanvas = props.onCloseCanvas ?? (() => {}); @@ -55,6 +58,7 @@ const [lockupStakedPoolsWithBalance, setLockupStakedPoolsWithBalance] = const [hasUnstakedAssets, setHasUnstakedAssets] = useState(true); const [isReadyToWithdraw, setIsReadyToWithdraw] = useState(true); const [showLoader, setShowLoader] = useState(true); +const [showErrorToast, setShowErrorToast] = useState(false); function formatNearAmount(amount) { return Big(amount ?? "0") @@ -114,18 +118,35 @@ useEffect(() => { useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { + cleanInputs(); onCloseCanvas(); refreshData(); + clearTimeout(errorTimeout); setTxnCreated(false); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -357,6 +378,11 @@ const Container = styled.div` return ( + setShowErrorToast(false)} + /> { } return (
- {content} -
- {showToastStatus !== "InProgress" && showToastStatus !== "Removed" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -235,7 +243,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/playwright-tests/tests/payments/create-payment-request.spec.js b/playwright-tests/tests/payments/create-payment-request.spec.js index 5bd91633..1826f614 100644 --- a/playwright-tests/tests/payments/create-payment-request.spec.js +++ b/playwright-tests/tests/payments/create-payment-request.spec.js @@ -594,6 +594,7 @@ test.describe("admin with function access keys", function () { expectedTransactionModalObject ); + await expect(page.getByText("Processing your request ...")).toBeVisible(); let isTransactionCompleted = false; let retryCountAfterComplete = 0; let newProposalId; diff --git a/playwright-tests/tests/payments/vote-on-request.spec.js b/playwright-tests/tests/payments/vote-on-request.spec.js index 22bbf5d5..9304f174 100644 --- a/playwright-tests/tests/payments/vote-on-request.spec.js +++ b/playwright-tests/tests/payments/vote-on-request.spec.js @@ -211,6 +211,7 @@ test.describe("don't ask again", function () { await expect(approveButton).toBeEnabled({ timeout: 30_000 }); await approveButton.click(); await page.getByRole("button", { name: "Confirm" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect(approveButton).toBeDisabled(); const transaction_toast = page.getByText( @@ -266,6 +267,7 @@ test.describe("don't ask again", function () { await expect(rejectButton).toBeEnabled({ timeout: 10000 }); await rejectButton.click(); await page.getByRole("button", { name: "Confirm" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect(rejectButton).toBeDisabled(); const transaction_toast = page.getByText( @@ -321,6 +323,8 @@ test.describe("don't ask again", function () { page.getByText("Do you really want to delete this request?") ).toBeVisible(); await page.getByRole("button", { name: "Confirm" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(deleteButton).toBeDisabled(); const transaction_toast = page.getByText( diff --git a/playwright-tests/tests/settings/create-member-request.spec.js b/playwright-tests/tests/settings/create-member-request.spec.js index 61105715..7b00f4e5 100644 --- a/playwright-tests/tests/settings/create-member-request.spec.js +++ b/playwright-tests/tests/settings/create-member-request.spec.js @@ -165,7 +165,7 @@ test.describe("User is logged in", function () { const submitBtn = await page.locator("button", { hasText: "Submit" }); await submitBtn.scrollIntoViewIfNeeded({ timeout: 10_000 }); await submitBtn.click(); - + await expect(page.getByText("Processing your request ...")).toBeVisible(); const description = { title: "Update policy - Members Permissions", summary: `theori.near requested to add "${account}" to "${permission}".`, @@ -442,6 +442,7 @@ test.describe("User is logged in", function () { await expect(submitBtn).toBeAttached({ timeout: 10_000 }); await submitBtn.scrollIntoViewIfNeeded({ timeout: 10_000 }); await submitBtn.click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); const description = { title: "Update policy - Members Permissions", summary: `theori.near requested to remove "${account}" from "${permission}".`, @@ -585,6 +586,8 @@ test.describe("User is logged in", function () { page.getByRole("heading", { name: "Are you sure?" }) ).toBeVisible(); await page.getByRole("button", { name: "Remove" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + const description = { title: "Update policy - Members Permissions", summary: `theori.near requested to requested to revoke all permissions of "megha19.near".`, diff --git a/playwright-tests/tests/settings/create-threshold-request.spec.js b/playwright-tests/tests/settings/create-threshold-request.spec.js index e5856110..4188d438 100644 --- a/playwright-tests/tests/settings/create-threshold-request.spec.js +++ b/playwright-tests/tests/settings/create-threshold-request.spec.js @@ -148,6 +148,7 @@ test.describe("User is logged in", function () { ) ).toBeVisible(); await page.getByRole("button", { name: "Confirm" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); const updatedPolicy = { weight_kind: "RoleWeight", quorum: "0", @@ -189,6 +190,8 @@ test.describe("User is logged in", function () { ) ).toBeVisible(); await page.getByRole("button", { name: "Confirm" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + const updatedPolicy = { weight_kind: "RoleWeight", quorum: "0", diff --git a/playwright-tests/tests/settings/theme.spec.js b/playwright-tests/tests/settings/theme.spec.js index 2e15d4ba..f9ae6fcd 100644 --- a/playwright-tests/tests/settings/theme.spec.js +++ b/playwright-tests/tests/settings/theme.spec.js @@ -102,6 +102,8 @@ test.describe("User is logged in", function () { await expect(submitBtn).toBeDisabled(submitBtn); await logoInput.setInputFiles(path.join(__dirname, "./assets/valid.jpg")); await submitBtn.click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Title: Update Config - Theme & logo", @@ -127,6 +129,8 @@ test.describe("User is logged in", function () { await page.getByTestId("dropdown-btn").click(); await page.getByText("Light").click(); await page.getByRole("button", { name: "Save changes" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Title: Update Config - Theme & logo", @@ -145,4 +149,18 @@ test.describe("User is logged in", function () { }, }); }); + + test("should display a transaction error toast when the transaction confirmation modal is canceled", async ({ + page, + }) => { + test.setTimeout(150_000); + await page.getByRole("button", { name: "Save changes" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await page.getByRole("button", { name: "Close" }).nth(1).click(); + await expect( + page.getByText( + "Something went wrong. Please try resubmitting the request" + ) + ).toBeVisible({ timeout: 30_000 }); + }); }); diff --git a/playwright-tests/tests/settings/voting-duration.spec.js b/playwright-tests/tests/settings/voting-duration.spec.js index 48ad3a77..92ff2991 100644 --- a/playwright-tests/tests/settings/voting-duration.spec.js +++ b/playwright-tests/tests/settings/voting-duration.spec.js @@ -154,7 +154,6 @@ test.describe("User is logged in", function () { return new Promise((resolve) => { wallet.signAndSendTransaction = async (transaction) => { - console.log("transactions", JSON.stringify(transaction)); resolve(transaction); return await new Promise( (transactionSentPromiseResolve) => @@ -179,7 +178,7 @@ test.describe("User is logged in", function () { await page.evaluate((transactionResult) => { window.transactionSentPromiseResolve(transactionResult); }, transactionResult); - await expect(page.locator(".toast-header")).toBeVisible(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect( page.getByText("Voting duration change request submitted") ).toBeVisible(); diff --git a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js index 1f2a3e0a..bd10d964 100644 --- a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js +++ b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js @@ -505,6 +505,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio .first() .inputValue(); await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Proposal Action: stake", @@ -540,6 +541,8 @@ test.describe("Have valid staked requests and sufficient token balance", functio errorText: "The amount exceeds the balance you have staked.", }); await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Proposal Action: unstake", @@ -656,6 +659,7 @@ test.describe("Withdraw request", function () { const submitBtn = page.getByRole("button", { name: "Submit" }); await expect(submitBtn).toBeEnabled(); await submitBtn.click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: `* Proposal Action: withdraw`, @@ -711,6 +715,7 @@ test.describe("Withdraw request", function () { ).toBeVisible({ timeout: 10_000, }); + await expect(page.getByText("Processing your request ...")).toBeVisible(); // proposals for both the pools await expect(await getTransactionModalObject(page)).toEqual({ proposal: { @@ -888,6 +893,8 @@ test.describe("Lockup staking", function () { errorText: "Your account doesn't have sufficient balance.", }); await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: @@ -1002,6 +1009,8 @@ test.describe("Lockup staking", function () { errorText: "Your account doesn't have sufficient balance.", }); await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Proposal Action: stake", @@ -1049,6 +1058,8 @@ test.describe("Lockup staking", function () { errorText: "The amount exceeds the balance you have staked.", }); await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); + await expect(await getTransactionModalObject(page)).toEqual({ proposal: { description: "* Proposal Action: unstake",