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

Test/e2e phase 1 #450

Merged
merged 20 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/ui_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
env:
VITE_PROJECT_ID: ${{ secrets.VITE_DEV_PROJECT_ID }}
VITE_EXPLORER_API_URL: ${{ secrets.VITE_EXPLORER_API_URL }}
TEST_DAPP_PROJECT_ID: ${{ secrets.TEST_DAPP_PROJECT_ID }}
TEST_DAPP_PROJECT_SECRET: ${{ secrets.TEST_DAPP_PROJECT_SECRET }}
VITE_CI: true
- uses: actions/upload-artifact@v3
if: always()
Expand Down
4 changes: 0 additions & 4 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ export default defineConfig({
name: 'firefox',
use: { ...devices['Desktop Firefox'] }
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] }
}
],

/* Run your local dev server before starting the tests */
Expand Down
10 changes: 10 additions & 0 deletions tests/shared/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ export const DEFAULT_SESSION_PARAMS: SessionParams = {
optAccounts: ['1', '2'],
accept: true
}

export const CUSTOM_TEST_DAPP = {
description: "Test description",
icons: ["https://i.imgur.com/q9QDRXc.png"],
name: "Notify Swift Integration Tests Prod",
bkrem marked this conversation as resolved.
Show resolved Hide resolved
appDomain: "wc-notify-swift-integration-tests-prod.pages.dev",
projectSecret: process.env['TEST_DAPP_PROJECT_SECRET'],
projectId: process.env['TEST_DAPP_PROJECT_ID'],
messageType: "f173f231-a45c-4dc0-aa5d-956eb04f7360"
} as const;
36 changes: 25 additions & 11 deletions tests/shared/fixtures/fixture.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import { test as base } from '@playwright/test'

import { ModalPage } from '../pages/InboxPage'
import { ModalValidator } from '../validators/ModalValidator'
import { InboxPage } from '../pages/InboxPage'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add a tests folder to absolute paths too. (But it might cause some issues on Jest, not really sure, might worth checking)

import { InboxValidator } from '../validators/ModalValidator'
import { SettingsPage } from '../pages/SettingsPage'
import { NotifyServer } from '../helpers/notifyServer'

// Declare the types of fixtures to use
export interface ModalFixture {
modalPage: ModalPage
modalValidator: ModalValidator
inboxPage: InboxPage
inboxValidator: InboxValidator
settingsPage: SettingsPage
notifyServer: NotifyServer
library: string
}

export const test = base.extend<ModalFixture>({
modalPage: async ({ page }, use) => {
const modalPage = new ModalPage(page)
await modalPage.load()
await use(modalPage)
inboxPage: async ({ page }, use) => {
const inboxPage = new InboxPage(page)
await inboxPage.load()
await use(inboxPage)
},
modalValidator: async ({ modalPage }, use) => {
const modalValidator = new ModalValidator(modalPage.page)
inboxValidator: async ({ inboxPage }, use) => {
const modalValidator = new InboxValidator(inboxPage.page)
await use(modalValidator)
}
},
// Have to pass same page object to maintain state between pages
settingsPage: async({ inboxPage }, use) => {
const settingsPage = new SettingsPage(inboxPage.page)
settingsPage.load()
use(settingsPage)
},
notifyServer: async({}, use) => {
const notifyServer = new NotifyServer();
use(notifyServer)
},
})
export { expect } from '@playwright/test'
53 changes: 53 additions & 0 deletions tests/shared/helpers/notifyServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { expect } from "@playwright/test"

export class NotifyServer {
private notifyBaseUrl = "https://notify.walletconnect.com"

public async sendMessage({
projectId,
projectSecret,
accounts,
url,
title,
body,
icon,
type
}: {
projectId: string,
projectSecret: string,
accounts: string[]
title: string,
body: string,
icon: string,
url: string
type: string
}) {
const request = JSON.stringify({
accounts,
notification: {
title,
body,
icon,
url,
type
}
})

const fetchUrl = `${this.notifyBaseUrl}/${projectId}/notify`

const headers = new Headers({
Authorization: `Bearer ${projectSecret}`,
"Content-Type": "application/json"
})

const fetchResults = await fetch(fetchUrl, {
method: "POST",
headers,
body: request
})

console.log({fetchResultsStatus: fetchResults.status, fetchResults: await fetchResults.text()})
devceline marked this conversation as resolved.
Show resolved Hide resolved

expect(fetchResults.status).toEqual(200)
}
}
70 changes: 65 additions & 5 deletions tests/shared/pages/InboxPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type Locator, type Page, expect } from '@playwright/test'

import { BASE_URL } from '../constants'

export class ModalPage {
export class InboxPage {
private readonly baseURL = BASE_URL

private readonly connectButton: Locator
Expand All @@ -12,7 +12,14 @@ export class ModalPage {
}

async load() {
await this.page.goto(this.baseURL)
await this.page.goto(`${this.baseURL}`)
devceline marked this conversation as resolved.
Show resolved Hide resolved
}

async gotoDiscoverPage() {
await this.page.locator('.Sidebar__Navigation__Link[href="/notifications"]').click()
await this.page.getByText('Discover Apps').click();

await this.page.getByText('Discover Web3Inbox').isVisible();
}

async copyConnectUriToClipboard() {
Expand Down Expand Up @@ -40,21 +47,74 @@ export class ModalPage {
await this.page.locator('.NotificationPwaModal__close-button').first().click()
}

async getAddress() {
await this.page.locator('.Avatar').first().click()
const address = await this.page.locator('wui-avatar').getAttribute('alt')
await this.page.locator('wui-icon[name=close]').first().click();

return address;
}

async subscribe(nth: number) {
await this.page.locator('.AppCard__body > .AppCard__body__subscribe').nth(nth).click()
await this.page.getByText('Subscribed to', { exact: false }).isVisible()
const appCard = this.page.locator('.AppCard__body').nth(nth)
await appCard.locator('.AppCard__body__subscribe').click()

await appCard.locator('.AppCard__body__subscribed').getByText('Subscribed', { exact: false }).isVisible()
}

async unsubscribe(nth: number) {
async navigateToNewSubscription(nth: number) {
await this.page.getByRole('button', { name: 'Subscribed' }).nth(nth).click()
await this.page.getByRole('button', { name: 'Subscribed' }).nth(nth).isHidden()
}

async subscribeAndNavigateToDapp(nth: number) {
await this.subscribe(nth);
await this.navigateToNewSubscription(nth);
}

async unsubscribe() {
await this.page.locator('.AppNotificationsHeader__wrapper > .Dropdown').click()
await this.page.getByRole('button', { name: 'Unsubscribe' }).click()
await this.page.getByRole('button', { name: 'Unsubscribe' }).nth(1).click()
await this.page.getByText('Unsubscribed from', { exact: false }).isVisible()
await this.page.waitForTimeout(2000)
}

async navigateToDappFromSidebar(nth: number) {
await this.page.locator('.AppSelector__notifications-link').nth(nth).click()
}

async countSubscribedDapps() {

devceline marked this conversation as resolved.
Show resolved Hide resolved
const selected = await this.page.locator('AppSelector__list').all()
return (await this.page.locator('.AppSelector__notifications').count() - 1)
devceline marked this conversation as resolved.
Show resolved Hide resolved
}

async updatePreferences() {
await this.page.locator('.AppNotificationsHeader__wrapper > .Dropdown').click()
await this.page.getByRole('button', { name: 'Preferences' }).click()
// Ensure the modal is visible
await this.page.getByText('Preferences').nth(1).isVisible()
await this.page.getByText('Preferences').nth(1).click()

const firstCheckBoxIsChecked = await this.page.isChecked('.Toggle__checkbox:nth-of-type(1)')
await expect(this.page.locator('.Toggle__label').first()).toBeVisible()

await this.page.locator('.Toggle').first().click()

await this.page.getByRole('button', { name: 'Update' }).click()


await this.page.locator('.AppNotificationsHeader__wrapper > .Dropdown').click()
await this.page.getByRole('button', { name: 'Preferences' }).click()

const firstCheckBoxIsCheckedAfterUpdating = await this.page.isChecked('.Toggle__checkbox:nth-of-type(1)')

expect(firstCheckBoxIsChecked).not.toEqual(firstCheckBoxIsCheckedAfterUpdating)

await this.page.locator('.PreferencesModal__close').click();
}

async cancelSiwe() {
await this.page.getByTestId('w3m-connecting-siwe-cancel').click()
}
Expand Down
21 changes: 21 additions & 0 deletions tests/shared/pages/SettingsPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { type Locator, type Page, expect } from '@playwright/test'

import { BASE_URL } from '../../shared/constants'

export class SettingsPage {
private readonly baseURL = BASE_URL

constructor(public readonly page: Page) {}

async load() {}

async goToNotificationSettings() {
await this.page.locator('.Sidebar__Navigation__Link[href="/settings"]').click()
}

async displayCustomDapp(dappUrl: string) {
await this.page.getByPlaceholder('app.example.com').fill(dappUrl)
await this.page.getByRole('button', { name: "Save", exact: true}).click()
}

}
2 changes: 1 addition & 1 deletion tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from '@playwright/test'
import type { Page } from '@playwright/test'

export class ModalValidator {
export class InboxValidator {
constructor(public readonly page: Page) {}

async expectConnected() {
Expand Down
Loading
Loading