Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ui test for crypto payment flow initiation and return #1933

Merged
merged 19 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { basePage } from "./basePage"
export const billingHistoryPage = {
...basePage,
billingHistoryHeader: () => cy.get("[data-cy=header-billing-history]"),
downloadInvoiceButton: () => cy.get("[data-testid=button-download-invoice]"),
payInvoiceButton: () => cy.get("[data-testid=button-pay-invoice]")
viewPdfButton: () => cy.get("[data-testid=button-download-invoice]"),
payNowButton: () => cy.get("[data-testid=button-pay-invoice]")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const cryptoPaymentModal = {
body: () => cy.get("[data-testid=modal-container-cryptoPayment]", { timeout: 10000 }),
closeButton: () => cy.get("[data-testid=button-close-modal-cryptoPayment]"),
payWithCryptoHeader: () => cy.get("[data-cy=header-pay-with-crypto]"),
cryptoPaymentTimer: () => cy.get("[data-cy=container-crypto-time-remaining]"),
totalLabel: () => cy.get("[data-cy=label-total-crypto-title]", { timeout: 10000 }),
totalPriceLabel: () => cy.get("[data-cy=label-total-crypto-price]"),
crypoPaymentErrorLabel: () => cy.get("[data-cy=label-crypto-payment-error]"),
selectCryptocurrencyLabel: () => cy.get("[data-cy=label-select-cryptocurrency]"),
cryptoPaymentButton: () => cy.get("[data-cy=container-crypto-payment-option]"),

// elements below only shown after crypto payment button has been clicked
receivingQrCodeContainer: () => cy.get("[data-cy=container-qr-code]"),
currencyTypeWarning: () => cy.get("[data-cy=label-currency-type-warning]"),
destinationAddressLabelTitle: () => cy.get("[data-cy=label-destination-address-title]"),
destinationAddressLabel: () => cy.get("[data-cy=label-destination-address]"),
cryptoAmountTitleLabel: () => cy.get("[data-cy=label-crypto-amount-title]"),
cryptoAmountLabel: () => cy.get("[data-cy=label-crypto-amount]"),
crypoFinalSaleWarningLabel: () => cy.get("[data-cy=label-crypto-final-sale-warning]"),
goBackButton: () => cy.get("[data-testid=button-go-back-to-crypto-selection]"),
switchNetworkButton: () => cy.get("[data-testid=button-switch-network]"),
connectWalletButton: () => cy.get("[data-testid=button-connect-wallet]")
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ export const planChangeConfirmationModal = {
totalLabel: () => cy.get("[data-cy=label-total-title]"),
totalPriceLabel: () => cy.get("[data-cy=label-total-price]"),
changePlanErrorLabel: () => cy.get("[data-cy=label-change-plan-error]"),
planPaymentWarningLabel: () => cy.get("[data-cy=label-change-plan-payment-warning]"),
goBackButton: () => cy.get("[data-testid=button-go-back-to-payment-method]"),
confirmPlanChangeButton: () => cy.get("[data-testid=button-confirm-plan-change]")
confirmPlanChangeButton: () => cy.get("[data-testid=button-confirm-plan-change]"),
finalSaleWarningLabel: () => cy.get("[data-cy=label-final-sale-warning]"),

// elements are only displayed if the payment type is crypto
payWithCryptoLabel: () => cy.get("[data-cy=label-pay-with-crypto]"),
acceptedCurrenciesLabel: () => cy.get("[data-cy=label-accepted-currencies]"),
acceptedCryptoTypes: () => cy.get("[data-cy=label-accepted-crypto-types]")
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export const settingsPage = {
noCardLabel: () => cy.get("[data-cy=label-no-card]"),
removeCardLink: () => cy.get("[data-cy=link-remove-card]"),
changePlanButton: () => cy.get("[data-cy=button-change-plan]", { timeout: 10000 }),
allInvoicesLink: () => cy.get("[data-cy=link-all-invoices]"),
viewPdfButton: () => cy.get("[data-testid=button-download-invoice]"),
payNowButton: () => cy.get("[data-testid=button-pay-invoice]"),

// use this convenience function when an upgraded account is required as a test requisite
upgradeSubscription(plan: "standard" | "premium") {
Expand Down
67 changes: 65 additions & 2 deletions packages/files-ui/cypress/tests/subscription-plan-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { planChangeConfirmationModal } from "../support/page-objects/modals/bill
import { planChangeSuccessModal } from "../support/page-objects/modals/billing/planChangeSuccessModal"
import { billingHistoryPage } from "../support/page-objects/billingHistoryPage"
import { downgradeDetailsModal } from "../support/page-objects/modals/billing/downgradeDetailsModal"
import { cryptoPaymentModal } from "../support/page-objects/modals/billing/cryptoPaymentModal"

describe("Subscription Plan", () => {

Expand Down Expand Up @@ -326,7 +327,7 @@ describe("Subscription Plan", () => {
planChangeConfirmationModal.billingStartDate().should("be.visible")
planChangeConfirmationModal.totalLabel().should("be.visible")
planChangeConfirmationModal.totalPriceLabel().should("be.visible")
planChangeConfirmationModal.planPaymentWarningLabel().should("be.visible")
planChangeConfirmationModal.finalSaleWarningLabel().should("be.visible")
planChangeConfirmationModal.goBackButton().should("be.visible")
planChangeConfirmationModal.confirmPlanChangeButton().should("be.visible")

Expand Down Expand Up @@ -356,7 +357,7 @@ describe("Subscription Plan", () => {
expect($request).to.be.null
})

billingHistoryPage.downloadInvoiceButton().first().click()
billingHistoryPage.viewPdfButton().first().click()

// ensure the download request contains pdf content
cy.wait("@downloadRequest").its("response.headers").should("contain", {
Expand Down Expand Up @@ -459,5 +460,67 @@ describe("Subscription Plan", () => {
cy.get("@freePlanName").should("not.equal", $standardPlanName)
})
})

it("can initiate and return to a crypto payment flow within 60 minutes", () => {
cy.web3Login({ deleteCreditCard: true, resetToFreePlan: true })
navigationMenu.settingsNavButton().click()
settingsPage.subscriptionTabButton().click()
settingsPage.changePlanButton().click()
selectPlanModal.createPlanCypressAliases()
cy.get("@standardPlanBox").parent().within(() => {
selectPlanModal.selectPlanButton().click()
})

// choose crypto as payment type
planDetailsModal.durationToggleSwitch().click()
planDetailsModal.selectThisPlanButton().click()
selectPaymentMethodModal.cryptoRadioInput()
.should("be.visible")
.click()
selectPaymentMethodModal.selectPaymentButton().click()

// ensure crypto payment specific elements are displayed
planChangeConfirmationModal.body().should("be.visible")
planChangeConfirmationModal.payWithCryptoLabel().should("be.visible")
planChangeConfirmationModal.acceptedCurrenciesLabel().should("be.visible")
planChangeConfirmationModal.acceptedCryptoTypes().should("be.visible")
planChangeConfirmationModal.finalSaleWarningLabel().should("be.visible")
planChangeConfirmationModal.confirmPlanChangeButton().click()

// ensure default crypto elements are displayed
cryptoPaymentModal.body().should("be.visible")
cryptoPaymentModal.payWithCryptoHeader().should("be.visible")
cryptoPaymentModal.totalLabel().should("be.visible")
cryptoPaymentModal.cryptoPaymentTimer().should("be.visible")
cryptoPaymentModal.totalPriceLabel().should("be.visible")
cryptoPaymentModal.selectCryptocurrencyLabel().should("be.visible")

// choose a crypto currency
cryptoPaymentModal.cryptoPaymentButton().contains("Ethereum").click()

// ensure additional modal elements are displayed after crypto type is selected
cryptoPaymentModal.receivingQrCodeContainer().should("be.visible")
cryptoPaymentModal.currencyTypeWarning().should("be.visible")
cryptoPaymentModal.destinationAddressLabelTitle().should("be.visible")
cryptoPaymentModal.destinationAddressLabel().should("be.visible")
cryptoPaymentModal.cryptoAmountTitleLabel().should("be.visible")
cryptoPaymentModal.cryptoAmountLabel().should("be.visible")
cryptoPaymentModal.crypoFinalSaleWarningLabel().should("be.visible")
cryptoPaymentModal.goBackButton().should("be.visible")
cryptoPaymentModal.connectWalletButton().should("be.visible")

// close modal, ensure we can return to flow via "pay now" on settings page
cryptoPaymentModal.closeButton().click()
cryptoPaymentModal.body().should("not.exist")
settingsPage.payNowButton().click()
cryptoPaymentModal.body().should("be.visible")

// close modal, ensure we can return to flow via "pay now" on billing history page
cryptoPaymentModal.closeButton().click()
cryptoPaymentModal.body().should("not.exist")
settingsPage.allInvoicesLink().click()
billingHistoryPage.payNowButton().click()
cryptoPaymentModal.body().should("be.visible")
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ const BillingHistory = () => {
component="p"
className={classes.link}
>
<Link to={ROUTE_LINKS.BillingHistory}>
<Link
to={ROUTE_LINKS.BillingHistory}
data-cy="link-all-invoices"
>
<Trans>All invoices</Trans>
</Link>
</Typography>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ const ConfirmPlan = ({
<Typography
variant="body1"
component="p"
data-cy="label-pay-with-crypto"
>
<Trans>Pay with Crypto</Trans>
</Typography>
Expand All @@ -247,13 +248,15 @@ const ConfirmPlan = ({
<Typography
component="p"
variant="body1"
data-cy="label-accepted-currencies"
>
<Trans>Accepted currencies</Trans>
</Typography>
<div className={classes.pushRightBox}>
<Typography
variant="body1"
component="p"
data-cy="label-accepted-crypto-types"
>
DAI, USDC, ETH or BTC
</Typography>
Expand Down Expand Up @@ -308,7 +311,7 @@ const ConfirmPlan = ({
variant="body1"
component="p"
className={classes.warningText}
data-cy="label-change-plan-payment-warning"
data-cy="label-final-sale-warning"
>
<InfoCircleIcon className={classes.icon} />
{paymentMethod === "crypto"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,20 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
variant="h5"
component="h4"
className={classes.heading}
data-cy="header-pay-with-crypto"
>
<Trans>Pay with crypto</Trans>
</Typography>
{cryptoPayment && <div className={classes.pushRightBox}>
{cryptoPayment && <div
className={classes.pushRightBox}
data-cy="container-crypto-time-remaining"
>
<CircularProgressBar
progress={(timeRemaining?.as("s") || 0) / 3600 * 100}
width={23}
label={timeRemaining?.format("mm:ss") || ""}
variant="secondary"
data-cy="label-select-cryptocurrency"
/>
</div>}
</div>
Expand All @@ -388,25 +393,32 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
component="p"
variant="body1"
className={classes.error}
data-cy="label-crypto-payment-error"
>
<Trans>Failed to create a charge</Trans>
</Typography>
}
{cryptoPayment && pendingCryptoInvoice &&
<>
<div className={classes.rowBox}>
<Typography>Total</Typography>
<Typography data-cy="label-total-crypto-title">
Total
</Typography>
<div className={classes.pushRightBox}>
<Typography>
<Typography data-cy="label-total-crypto-price">
{pendingCryptoInvoice.currency?.toUpperCase()} {pendingCryptoInvoice.amount}
</Typography>
</div>
</div>
<Divider />
{!selectedCurrency && currencies &&
<>
<Typography>Select a cryptocurrency</Typography>
<div className={classes.availableCurrencies}>
<Typography data-cy="label-select-cryptocurrency">
<Trans>Select a cryptocurrency</Trans>
</Typography>
<div
className={classes.availableCurrencies}
data-cy="container-crypto-payment-option">
{currencies.map(c => {
const CurrencyIcon = iconMap[c] || null
return <Button
Expand All @@ -423,23 +435,28 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
}
{selectedCurrency && selectedPaymentMethod &&
<>
<div className={classes.qrCode}>
<div
className={classes.qrCode}
data-cy="container-qr-code"
>
<QRCode
value={selectedPaymentMethod.address}
size={128}
/>
</div>
<div className={classes.qrCodeLabel}>
<Typography>
<Typography data-cy="label-currency-type-warning">
<Trans>Only send {selectedCurrency} to this address</Trans>
</Typography>
</div>
<Divider />
<Typography><Trans>Destination Address</Trans></Typography>
<Typography data-cy="label-destination-address-title">
<Trans>Destination Address</Trans>
</Typography>
<div
className={clsx(classes.rowBox, classes.copyRow)}
onClick={onCopyDestinationAddress}>
<Typography>{selectedPaymentMethod.address}</Typography>
<Typography data-cy="label-destination-address">{selectedPaymentMethod.address}</Typography>
<div className={classes.pushRightBox}>
<CopyIcon className={classes.copyIcon} />
<div className={clsx(classes.copiedFlag, { "active": copiedDestinationAddress })}>
Expand All @@ -451,12 +468,14 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
</div>
</div>
</div>
<Typography><Trans>Total Amount</Trans></Typography>
<Typography data-cy="label-crypto-amount-title">
<Trans>Total Amount</Trans>
</Typography>
<div
className={clsx(classes.rowBox, classes.copyRow)}
onClick={onCopyAmount}
>
<Typography>
<Typography data-cy="label-crypto-amount">
{selectedPaymentMethod.amount} {symbolMap[selectedCurrency]}
</Typography>
<div className={classes.pushRightBox}>
Expand All @@ -474,7 +493,7 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
variant="body1"
component="p"
className={classes.warningText}
data-cy="label-crypto-payment-warning"
data-cy="label-crypto-final-sale-warning"
>
<InfoCircleIcon className={classes.icon} />
<Trans>
Expand All @@ -491,14 +510,23 @@ const CryptoPayment = ({ planPrice }: ICryptoPayment) => {
{!!selectedCurrency && <Button
onClick={() => setSelectedCurrency(undefined)}
variant="text"
testId="go-back-to-crypto-selection"
>
<Trans>Go back</Trans>
</Button>}
{selectedCurrency && selectedCurrency !== "bitcoin" && !isReady &&
<Button onClick={selectWallet}><Trans>Connect Wallet</Trans></Button>
<Button
onClick={selectWallet}
testId="connect-wallet"
>
<Trans>Connect Wallet</Trans>
</Button>
}
{selectedCurrency && selectedCurrency !== "bitcoin" && isReady && network !== 1 &&
<Button onClick={handleSwitchNetwork}>
<Button
onClick={handleSwitchNetwork}
testId="switch-network"
>
<Trans>Switch Network</Trans>
</Button>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const PayInvoiceModal = ({ onClose, invoiceId }: IChangeProductModal) => {
injectedClass={{
inner: classes.inner
}}
testId="pay-invoice"
testId="cryptoPayment"
onClose={onClose}
>
{invoiceToPay?.payment_method === "crypto"
Expand Down