Skip to content

Commit

Permalink
feat(3765): Add modal to include metric id before redirecting to supp…
Browse files Browse the repository at this point in the history
…ort page (#30415)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
We currently redirect users to this url when they reach out to support:
https://support.metamask.io/

We should update Extension client in order to redirect users to this url
when they reach out to support:
https://support.metamask.io/?metamask_version=11.16.12&metamask_profile_id=d9b2d63d-a233-4d4d-bd4b-5b3d5a6e2c5d&metamask_metametrics_id=f3b9c1d2-4a5e-4b6f-9e2d-8c4f7a1b3c6d

Passing MetaMask Identifier and the version of the app to support can
help facilitate debugging on our side.

This PR added 2 entry points for this feature: 
- settings page
- when page crushes and lead to error page 

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30415?quickstart=1)

## **Related issues**

Fixes: MetaMask/MetaMask-planning#3765

## **Manual testing steps**

1. Go to settings => about => visit our support center 
2. Choose confirm or don't share to proceed
3. Confirm with lead to MM support site with URL including version,
metametricsId, profileId
4. Don't share will lead to `https://support.metamask.io/` 
5. Go to developer options => trigger a page crash
6. Click contact support
7. The behavior is the same as above

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

https://www.loom.com/share/9a45da1640104488abb2c7b7000dbdc9?sid=069eee12-f244-44b6-8947-c213208570364
<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
DDDDDanica authored Feb 24, 2025
1 parent 16c2173 commit 4ec2d26
Show file tree
Hide file tree
Showing 16 changed files with 537 additions and 78 deletions.
12 changes: 12 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions app/_locales/en_GB/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion test/e2e/page-objects/pages/error-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ class ErrorPage {
private readonly sentryFeedbackSuccessModal =
'[data-testid="error-page-sentry-feedback-success-modal"]';

private readonly visitSupportDataConsentModal =
'[data-testid="visit-support-data-consent-modal"]';

private readonly visitSupportDataConsentModalAcceptButton =
'[data-testid="visit-support-data-consent-modal-accept-button"]';

private readonly visitSupportDataConsentModalRejectButton =
'[data-testid="visit-support-data-consent-modal-reject-button"]';

constructor(driver: Driver) {
this.driver = driver;
}
Expand Down Expand Up @@ -78,14 +87,29 @@ class ErrorPage {
);
}

async contactAndValidateMetaMaskSupport(): Promise<void> {
async clickContactButton(): Promise<void> {
console.log(`Contact metamask support form in a separate page`);
await this.driver.waitUntilXWindowHandles(1);
await this.driver.clickElement(this.contactSupportButton);
}

async consentDataToMetamaskSupport(): Promise<void> {
await this.driver.waitForSelector(this.visitSupportDataConsentModal);
await this.driver.clickElementAndWaitToDisappear(
this.visitSupportDataConsentModalAcceptButton,
);
// metamask, help page
await this.driver.waitUntilXWindowHandles(2);
}

async rejectDataToMetamaskSupport(): Promise<void> {
await this.driver.waitForSelector(this.visitSupportDataConsentModal);
await this.driver.clickElementAndWaitToDisappear(
this.visitSupportDataConsentModalRejectButton,
);
await this.driver.waitUntilXWindowHandles(2);
}

async waitForSentrySuccessModal(): Promise<void> {
await this.driver.waitForSelector(this.sentryFeedbackSuccessModal);
await this.driver.assertElementNotPresent(this.sentryFeedbackSuccessModal);
Expand Down
36 changes: 33 additions & 3 deletions test/e2e/tests/metrics/developer-options-sentry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SettingsPage from '../../page-objects/pages/settings/settings-page';
import HeaderNavbar from '../../page-objects/pages/header-navbar';
import DevelopOptions from '../../page-objects/pages/developer-options-page';
import ErrorPage from '../../page-objects/pages/error-page';
import { MOCK_META_METRICS_ID } from '../../constants';

const triggerCrash = async (driver: Driver): Promise<void> => {
const headerNavbar = new HeaderNavbar(driver);
Expand Down Expand Up @@ -41,7 +42,7 @@ describe('Developer Options - Sentry', function (this: Suite) {
{
fixtures: new FixtureBuilder()
.withMetaMetricsController({
metaMetricsId: 'fake-metrics-id',
metaMetricsId: MOCK_META_METRICS_ID,
participateInMetaMetrics: true,
})
.build(),
Expand All @@ -64,7 +65,35 @@ describe('Developer Options - Sentry', function (this: Suite) {
);
});

it('gives option to cause a page crash and offer contact support option', async function () {
it('gives option to cause a page crash and offer contact support option with consenting to share data', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder()
.withMetaMetricsController({
metaMetricsId: MOCK_META_METRICS_ID,
participateInMetaMetrics: true,
})
.build(),
title: this.test?.fullTitle(),
ignoredConsoleErrors: [
'Error#1: Unable to find value of key "developerOptions" for locale "en"',
'React will try to recreate this component tree from scratch using the error boundary you provided, Index.',
],
},
async ({ driver }: { driver: Driver }) => {
await loginWithBalanceValidation(driver);
await triggerCrash(driver);

const errorPage = new ErrorPage(driver);
await errorPage.check_pageIsLoaded();

await errorPage.clickContactButton();
await errorPage.consentDataToMetamaskSupport();
},
);
});

it('gives option to cause a page crash and offer contact support option with rejecting to share data', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder().build(),
Expand All @@ -81,7 +110,8 @@ describe('Developer Options - Sentry', function (this: Suite) {
const errorPage = new ErrorPage(driver);
await errorPage.check_pageIsLoaded();

await errorPage.contactAndValidateMetaMaskSupport();
await errorPage.clickContactButton();
await errorPage.rejectDataToMetamaskSupport();
},
);
});
Expand Down
1 change: 1 addition & 0 deletions ui/components/app/modals/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@import 'transaction-confirmed/index';
@import 'customize-nonce/index';
@import 'convert-token-to-nft-modal/index';
@import 'visit-support-data-consent-modal/index';

.modal {
z-index: 1050;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`VisitSupportDataConsentModal renders the modal correctly when open 1`] = `
<div
class="mm-modal visit-support-data-consent-modal"
data-testid="visit-support-data-consent-modal"
>
<div
aria-hidden="true"
class="mm-box mm-modal-overlay mm-box--width-full mm-box--height-full mm-box--background-color-overlay-default"
/>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
data-focus-lock-disabled="false"
>
<div
class="mm-box mm-modal-content mm-box--padding-top-4 mm-box--sm:padding-top-8 mm-box--md:padding-top-12 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--sm:padding-bottom-8 mm-box--md:padding-bottom-12 mm-box--padding-left-4 mm-box--display-flex mm-box--justify-content-center mm-box--align-items-flex-start mm-box--width-screen mm-box--height-screen"
>
<section
aria-modal="true"
class="mm-box mm-modal-content__dialog mm-modal-content__dialog--size-sm mm-box--padding-top-4 mm-box--padding-bottom-4 mm-box--display-flex mm-box--flex-direction-column mm-box--width-full mm-box--background-color-background-default mm-box--rounded-lg"
role="dialog"
>
<header
class="mm-box mm-header-base mm-modal-header mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--padding-left-4 mm-box--display-flex mm-box--justify-content-space-between"
>
<div
class="mm-box mm-box--width-full"
>
<h4
class="mm-box mm-text mm-text--heading-sm mm-text--text-align-center mm-box--color-text-default"
>
Share device details with support
</h4>
</div>
</header>
<div
class="mm-box mm-modal-body visit-support-data-consent-modal__body mm-box--padding-right-4 mm-box--padding-left-4"
>
<p
class="mm-box mm-text mm-text--body-md mm-box--color-text-default"
>
Do you want to share your MetaMask Identifier and app version with our Support Center? This can help us better solve your problem, but is optional.
</p>
</div>
<div
class="mm-box mm-modal-footer mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-left-4"
>
<div
class="mm-box mm-box--display-flex mm-box--gap-4"
>
<button
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-button-secondary mm-text--body-md-medium mm-box--padding-0 mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--width-1/2 mm-box--color-primary-default mm-box--background-color-transparent mm-box--rounded-pill mm-box--border-color-primary-default box--border-style-solid box--border-width-1"
data-testid="visit-support-data-consent-modal-reject-button"
>
Don’t share
</button>
<button
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-button-primary mm-text--body-md-medium mm-box--padding-0 mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--width-1/2 mm-box--color-primary-inverse mm-box--background-color-primary-default mm-box--rounded-pill"
data-testid="visit-support-data-consent-modal-accept-button"
data-theme="light"
>
Confirm
</button>
</div>
<div
class="mm-box mm-container mm-container--max-width-sm mm-box--margin-right-auto mm-box--margin-left-auto mm-box--display-flex mm-box--gap-4 mm-box--flex-wrap-wrap mm-box--align-items-center"
/>
</div>
</section>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@use 'design-system';

.visit-support-data-consent-modal {
&__body {
&__preference-checkbox {
margin-top: 16px;
margin-bottom: 16px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './visit-support-data-consent-modal';
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import VisitSupportDataConsentModal from '.';

export default {
title: 'Components/App/Modals/VisitSupportDataConsentModal',
};

export const DefaultStory = () => (
<VisitSupportDataConsentModal
isOpen
onClose={() => {}}
/>
);

DefaultStory.storyName = 'Default';
Loading

0 comments on commit 4ec2d26

Please sign in to comment.