Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat: added notification snap to methods-snap #137 (#166)
Browse files Browse the repository at this point in the history
* pair improvements

* fix lint

* feat: add notify Snap method

* Added getAllNotifications method

* go back after getting all notifications

* remove timeout

* fix post merge errors

Co-authored-by: Bernard <bero4net@gmail.com>
Co-authored-by: Marin Petrunic <marin.petrunic@gmail.com>
  • Loading branch information
3 people committed Dec 15, 2022
1 parent c4c0e5f commit ae17944
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 21 deletions.
3 changes: 2 additions & 1 deletion src/metamask/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DappeteerPage } from "../page";

import { acceptDialog } from "../snap/acceptDialog";
import { rejectDialog } from "../snap/rejectDialog";
import { installSnap, invokeSnap } from "../snap";
import { getAllNotifications, installSnap, invokeSnap } from "../snap";
import { addNetwork } from "./addNetwork";
import { addToken } from "./addToken";
import { approve } from "./approve";
Expand Down Expand Up @@ -55,6 +55,7 @@ export const getMetaMask = (page: DappeteerPage): Promise<Dappeteer> => {
deleteNetwork: deleteNetwork(page),
},
snaps: {
getAllNotifications: getAllNotifications(page),
acceptDialog: acceptDialog(page),
rejectDialog: rejectDialog(page),
invokeSnap,
Expand Down
10 changes: 7 additions & 3 deletions src/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { DappeteerElementHandle } from "./element";

export interface DappeteerPage<P = unknown> {
$(selector: string): Promise<DappeteerElementHandle | null>;
$eval(
$eval<T>(
selector: string,
evalFn: (e: HTMLElement) => Promise<void> | void
): Promise<void>;
evalFn: (e: HTMLElement) => Promise<T> | T
): Promise<T>;
$$eval<T>(
selector: string,
evalFn: (e: HTMLElement[]) => Promise<T[]> | T[]
): Promise<T[]>;
$$(selector: string): Promise<DappeteerElementHandle[]>;
getSource(): P;
url(): string;
Expand Down
18 changes: 11 additions & 7 deletions src/playwright/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ export class DPlaywrightPage implements DappeteerPage<Page> {
);
}

$eval(
$eval<T>(
selector: string,
evalFn: (e: HTMLElement) => void | Promise<void>
): Promise<void> {
return this.page.$eval(
selector,
async (e) => await evalFn(e as HTMLElement)
);
evalFn: (e: HTMLElement) => T | Promise<T>
): Promise<T> {
return this.page.$eval(selector, evalFn);
}

$$eval<T>(
selector: string,
evalFn: (e: HTMLElement[]) => T[] | Promise<T[]>
): Promise<T[]> {
return this.page.$$eval(selector, evalFn);
}

async $$(selector: string): Promise<DappeteerElementHandle<ElementHandle>[]> {
Expand Down
18 changes: 11 additions & 7 deletions src/puppeteer/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ export class DPupeteerPage implements DappeteerPage<Page> {
return new DPuppeteerElementHandle(await this.page.$(selector));
}

$eval(
$eval<T>(
selector: string,
evalFn: (e: HTMLElement) => void | Promise<void>
): Promise<void> {
return this.page.$eval(
selector,
async (e) => await evalFn(e as HTMLElement)
);
evalFn: (e: HTMLElement) => T | Promise<T>
): Promise<T> {
return this.page.$eval<T>(selector, evalFn) as Promise<T>;
}

$$eval<T>(
selector: string,
evalFn: (e: HTMLElement[]) => T[] | Promise<T[]>
): Promise<T[]> {
return this.page.$$eval(selector, evalFn);
}

async $$(selector: string): Promise<DappeteerElementHandle<ElementHandle>[]> {
Expand Down
22 changes: 22 additions & 0 deletions src/snap/getAllNotifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { clickOnElement, openProfileDropdown } from "../helpers";
import { DappeteerPage } from "../page";
import { NotificationList } from "./types";

export const getAllNotifications =
(page: DappeteerPage) => async (): Promise<NotificationList> => {
await page.bringToFront();
await openProfileDropdown(page);
await clickOnElement(page, "Notifications");
await page.waitForSelector(".notifications__item__details__message");
const notificationList: NotificationList = await page.$$eval(
".notifications__item__details__message",
(elements) =>
elements.map((element) => ({ message: element.textContent }))
);
const backButton = await page.waitForSelector(
".notifications__header__title-container__back-button"
);

await backButton.click();
return notificationList;
};
1 change: 1 addition & 0 deletions src/snap/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { flaskOnly } from "./utils";
export { installSnap } from "./install";
export { invokeSnap } from "./invokeSnap";
export { getAllNotifications } from "./getAllNotifications";
2 changes: 2 additions & 0 deletions src/snap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export interface InstallSnapResult {
};
};
}

export type NotificationList = { message: string }[];
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MetaMaskInpageProvider } from "@metamask/providers";
import { DappeteerPage, Serializable } from "./page";
import { Path } from "./setup/utils/metaMaskDownloader";
import { InstallStep } from "./snap/install";
import { InstallSnapResult } from "./snap/types";
import { InstallSnapResult, NotificationList } from "./snap/types";
import { RECOMMENDED_METAMASK_VERSION } from "./index";

export type DappeteerLaunchOptions = {
Expand Down Expand Up @@ -73,6 +73,7 @@ export type Dappeteer = {
};
page: DappeteerPage;
snaps: {
getAllNotifications: () => Promise<NotificationList>;
invokeSnap: <R = unknown, P extends Serializable = Serializable>(
page: DappeteerPage,
snapId: string,
Expand Down
2 changes: 1 addition & 1 deletion test/flask/methods-snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "An example Snap written in TypeScript.",
"proposedName": "Methods Snap\n",
"source": {
"shasum": "BCwqoDyQltaL0dh0IrzN1A66D1jPMLAseJOHmqI1faU=",
"shasum": "xxu7kMfZ4zKgviSZ5K4gZKSDDGEYi2VqOK5bKAqoybo=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
18 changes: 17 additions & 1 deletion test/flask/methods-snap/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { OnRpcRequestHandler } from "@metamask/snap-types";

export const onRpcRequest: OnRpcRequestHandler = ({ origin, request }) => {
export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
request,
}) => {
switch (request.method) {
case "confirm":
return wallet.request({
Expand All @@ -15,6 +18,19 @@ export const onRpcRequest: OnRpcRequestHandler = ({ origin, request }) => {
},
],
});
case "notify_inApp":
{
await wallet.request({
method: "snap_notify",
params: [
{
type: "inApp",
message: `Hello, in App notification`,
},
],
});
}
break;
default:
throw new Error("Method not found.");
}
Expand Down
12 changes: 12 additions & 0 deletions test/flask/snaps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,17 @@ describe("snaps", function () {

expect(await invokeAction).to.equal(false);
});

it("should invoke IN APP NOTIFICATIONS and check for a text", async function (this: TestContext) {
await metamask.snaps.invokeSnap(
testPage,
getSnapIdByName(this, Snaps.METHODS_SNAP),
"notify_inApp"
);

const notifications = await metamask.snaps.getAllNotifications();

expect(notifications[0].message).to.equal("Hello, in App notification");
});
});
});
1 change: 1 addition & 0 deletions test/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { deployContract, startLocalEthereum, startTestServer } from "./deploy";

export const mochaHooks = {
async beforeAll(this: Mocha.Context): Promise<void> {
this.timeout(100000);
const ethereum = await startLocalEthereum({
wallet: {
mnemonic: LOCAL_PREFUNDED_MNEMONIC,
Expand Down
1 change: 1 addition & 0 deletions test/global_flask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {

export const mochaHooks = {
async beforeAll(this: Mocha.Context): Promise<void> {
this.timeout(100000);
const ethereum = await startLocalEthereum({
wallet: {
mnemonic: LOCAL_PREFUNDED_MNEMONIC,
Expand Down

0 comments on commit ae17944

Please sign in to comment.