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

TW-823: [e2e] notifications #1021

Merged
merged 17 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .github/workflows/manual-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ jobs:
LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: ${{ secrets.LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }}
CUSTOM_NETWORK_RPC_URL: ${{ secrets.CUSTOM_NETWORK_RPC_URL }}
CUSTOM_NETWORK_SECOND_RPC_URL: ${{ secrets.CUSTOM_NETWORK_SECOND_RPC_URL }}
NOTIFICATION_AUTHORIZATION: ${{ secrets.NOTIFICATION_AUTHORIZATION }}

- name: Install dependencies and code quality
uses: ./.github/workflows/code-quality-check
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/secrets-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ inputs:
required: false
CUSTOM_NETWORK_SECOND_RPC_URL:
required: false
NOTIFICATION_AUTHORIZATION:
required: false

runs:
using: 'composite'
Expand Down Expand Up @@ -101,6 +103,8 @@ runs:
shell: bash
run: |
cat << EOF > e2e/.env
TEMPLE_WALLET_API_URL=${{ inputs.TEMPLE_WALLET_API_URL }}

DEFAULT_HD_ACCOUNT_SEED_PHRASE=${{ inputs.DEFAULT_HD_ACCOUNT_SEED_PHRASE }}
DEFAULT_HD_ACCOUNT_FIRST_PRIVATE_KEY=${{ inputs.DEFAULT_HD_ACCOUNT_FIRST_PRIVATE_KEY }}
DEFAULT_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH=${{ inputs.DEFAULT_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH }}
Expand All @@ -121,4 +125,5 @@ runs:
LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM=${{ inputs.LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }}
CUSTOM_NETWORK_RPC_URL=${{ inputs.CUSTOM_NETWORK_RPC_URL }}
CUSTOM_NETWORK_SECOND_RPC_URL=${{ inputs.CUSTOM_NETWORK_SECOND_RPC_URL }}
NOTIFICATION_AUTHORIZATION=${{ inputs.NOTIFICATION_AUTHORIZATION }}
EOF
2 changes: 2 additions & 0 deletions e2e/.env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM=

CUSTOM_NETWORK_RPC_URL=
CUSTOM_NETWORK_SECOND_RPC_URL=

NOTIFICATION_AUTHORIZATION=
1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"start:reveal_mnemonic": "yarn start --tags @reveal_mnemonic",
"start:send": "yarn start --tags @send",
"start:swap": "yarn start --tags @swap",
"start:notifications": "yarn start --tags @notifications",
"test": "yarn start --exit --tags 'not @dev'",
"ts": "tsc --pretty"
},
Expand Down
2 changes: 1 addition & 1 deletion e2e/src/features/import-account-by-mnemonic.feature
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Feature: Import Account by Mnemonic
Then I check if importedAccountByPasswordShortHash is corresponded to the selected account


@dev

Scenario: Import account by mnemonic validation + negative cases
Given I have imported an existing account

Expand Down
9 changes: 9 additions & 0 deletions e2e/src/features/manage-tokens-collectibles.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Feature: Manage tokens + collectibles

Scenario: As a user, I'd like to add tokens and collectibles to my wallet [Positive]
Given I have imported an existing account
And I press Selected Network Button on the Header page
And I select ECAD Labs Mainnet node in the networks drop-down list on the Header page
And I check that ECAD Labs Mainnet node is selected correctly
And I press Manage Dropdown Button on the Assets page
And I press Manage Button on the Assets (Manage Dropdown) page

Expand All @@ -28,6 +31,9 @@ Feature: Manage tokens + collectibles
@manage_assets
Scenario: As a user, I'd like to hide and delete tokens [Positive]
Given I have imported an existing account
And I press Selected Network Button on the Header page
And I select ECAD Labs Mainnet node in the networks drop-down list on the Header page
And I check that ECAD Labs Mainnet node is selected correctly
# hardcoded token

And I press Manage Dropdown Button on the Assets page
Expand Down Expand Up @@ -83,6 +89,9 @@ Feature: Manage tokens + collectibles
@manage_assets
Scenario: Validation check on Add Asset page + other checks [Negative]
Given I have imported an existing account
And I press Selected Network Button on the Header page
And I select ECAD Labs Mainnet node in the networks drop-down list on the Header page
And I check that ECAD Labs Mainnet node is selected correctly

And I press Manage Dropdown Button on the Assets page
And I press Manage Button on the Assets (Manage Dropdown) page
Expand Down
42 changes: 42 additions & 0 deletions e2e/src/features/notifications.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Feature: Notifications
@notifications
Scenario: As a user, I'd like to read some news
Given I make request for creating a notification
And I have imported an existing account
And I press Notification Icon Button on the Home page

And I am on the NotificationsList page
And I check that new notification is displayed
And I click on the new notification

And I am on the NotificationContent page
And The Notification Title Text on the Notification Content page has correct Test Title value
And The Notification Description Text on the Notification Content page has correct Test content value

And I press Got it Button on the Notification Content page
And I am on the NotificationsList page

And I press Account Icon on the Header page
And I am on the AccountsDropdown page

And I press Settings Button on the Account Drop-down page
And I am on the Settings page

And I press General Button on the Settings page
And I am on the GeneralSettings page
# turning off notifications
And I scroll 900 pixels on the GeneralSettings page
And I press Notification Check Box on the Setting General page

And I scroll -900 pixels on the GeneralSettings page
And I press Temple Logo Icon on the Header page
And I am on the Home page

And I press Notification Icon Button on the Home page
And I am on the NotificationsList page

Then I check that new notification is NOT displayed




9 changes: 8 additions & 1 deletion e2e/src/page-objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import { AddAssetPage } from 'e2e/src/page-objects/pages/add-asset.page';
import { AddressBookPage } from 'e2e/src/page-objects/pages/address-book.page';
import { ConfirmationModalPage } from 'e2e/src/page-objects/pages/confirmation-modal.page';
import { NetworksDropDown } from 'e2e/src/page-objects/pages/drop-down-lists/networks.drop-down';
// eslint-disable-next-line import/namespace
import { GeneralSettingsPage } from 'e2e/src/page-objects/pages/general-settings.page';
import { ManageAssetsCollectiblesPage } from 'e2e/src/page-objects/pages/manage-assets-collectibles.page';
import { ManageAssetsTokensPage } from 'e2e/src/page-objects/pages/manage-assets-tokens.page';
import { NetworksPage } from 'e2e/src/page-objects/pages/networks.page';
import { NewsletterModalPage } from 'e2e/src/page-objects/pages/newsletter-modal.page';
import { NotificationContentPage } from 'e2e/src/page-objects/pages/notification-content.page';
import { NotificationsListPage } from 'e2e/src/page-objects/pages/notifications-list.page';
import { OnRumModalPage } from 'e2e/src/page-objects/pages/on-rum-modal.page';
import {
OnboardingCongratsPage,
Expand Down Expand Up @@ -79,5 +83,8 @@ export const Pages = {
OnboardingSecondStep: new OnboardingSecondStepPage(),
OnboardingThirdStep: new OnboardingThirdStepPage(),
OnboardingFourthStep: new OnboardingFourthStepPage(),
OnboardingCongrats: new OnboardingCongratsPage()
OnboardingCongrats: new OnboardingCongratsPage(),
NotificationsList: new NotificationsListPage(),
NotificationContent: new NotificationContentPage(),
GeneralSettings: new GeneralSettingsPage()
};
29 changes: 29 additions & 0 deletions e2e/src/page-objects/pages/general-settings.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { SettingsGeneralSelectors } from 'src/app/templates/SettingsGeneral/selectors';

import { Page } from '../../classes/page.class';
import { createPageElement } from '../../utils/search.utils';

export class GeneralSettingsPage extends Page {
languageitem = createPageElement(SettingsGeneralSelectors.languageitem);
languageDropDown = createPageElement(SettingsGeneralSelectors.languageDropDown);
currencyItem = createPageElement(SettingsGeneralSelectors.currencyItem);
currenctyDropDown = createPageElement(SettingsGeneralSelectors.currenctyDropDown);
blockExplorerItem = createPageElement(SettingsGeneralSelectors.blockExplorerItem);
blockExplorerDropDown = createPageElement(SettingsGeneralSelectors.blockExplorerDropDown);
popUpCheckBox = createPageElement(SettingsGeneralSelectors.popUpCheckBox);
extensionLockUpCheckBox = createPageElement(SettingsGeneralSelectors.extensionLockUpCheckBox);
anonymousAnalyticsCheckBox = createPageElement(SettingsGeneralSelectors.anonymousAnalyticsCheckBox);
notificationCheckBox = createPageElement(SettingsGeneralSelectors.notificationCheckBox);
partnersPromotion = createPageElement(SettingsGeneralSelectors.partnersPromotion);

async isVisible() {
await this.languageDropDown.waitForDisplayed();
await this.currenctyDropDown.waitForDisplayed();
await this.blockExplorerDropDown.waitForDisplayed();
await this.popUpCheckBox.waitForDisplayed();
await this.extensionLockUpCheckBox.waitForDisplayed();
await this.anonymousAnalyticsCheckBox.waitForDisplayed();
await this.notificationCheckBox.waitForDisplayed();
await this.partnersPromotion.waitForDisplayed();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ImportAccountSelectors } from 'src/app/pages/ImportAccount/selectors';

import { Page } from 'e2e/src/classes/page.class';
import { EMPTY_WORD_FOR_INPUTS } from 'e2e/src/utils/input-data.utils';
import { clearDataFromInput, createPageElement, findElement, findElements } from 'e2e/src/utils/search.utils';
import { EMPTY_WORD_FOR_INPUTS, clearDataFromCurrentInput } from 'e2e/src/utils/input-data.utils';
import { createPageElement, findElement, findElements } from 'e2e/src/utils/search.utils';
import { SHORT_TIMEOUT } from 'e2e/src/utils/timing.utils';

export class ImportAccountMnemonicTab extends Page {
Expand Down Expand Up @@ -35,7 +35,7 @@ export class ImportAccountMnemonicTab extends Page {
const input = wordsInputs[i];

await input.focus();
await clearDataFromInput();
await clearDataFromCurrentInput();
}
}

Expand Down
6 changes: 4 additions & 2 deletions e2e/src/page-objects/pages/importing-existing-wallet.page.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ImportFromSeedPhraseSelectors } from 'src/app/pages/NewWallet/import/ImportSeedPhrase/ImportFromSeedPhrase.selectors';

import { clearDataFromCurrentInput } from 'e2e/src/utils/input-data.utils';

import { Page } from '../../classes/page.class';
import { clearDataFromInput, createPageElement, findElements } from '../../utils/search.utils';
import { createPageElement, findElements } from '../../utils/search.utils';

export class ImportExistingWalletPage extends Page {
nextButton = createPageElement(ImportFromSeedPhraseSelectors.nextButton);
Expand Down Expand Up @@ -31,7 +33,7 @@ export class ImportExistingWalletPage extends Page {
const input = wordsInputs[i];

await input.focus();
await clearDataFromInput();
await clearDataFromCurrentInput();
}
}
}
16 changes: 16 additions & 0 deletions e2e/src/page-objects/pages/notification-content.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NotificationsContentSelectors } from 'src/lib/notifications/components/item/notifications-content.selectors';

import { Page } from '../../classes/page.class';
import { createPageElement } from '../../utils/search.utils';

export class NotificationContentPage extends Page {
notificationContentTitle = createPageElement(NotificationsContentSelectors.notificationContentTitle);
notificationContentDescription = createPageElement(NotificationsContentSelectors.notificationContentDescription);
gotItButton = createPageElement(NotificationsContentSelectors.gotItButton);

async isVisible() {
await this.notificationContentTitle.waitForDisplayed();
await this.notificationContentDescription.waitForDisplayed();
await this.gotItButton.waitForDisplayed();
}
}
55 changes: 55 additions & 0 deletions e2e/src/page-objects/pages/notifications-list.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { PreviewItemSelectors } from 'src/lib/notifications/components/notifications/preview-item.selectors';
import type { NotificationInterface } from 'src/lib/notifications/types';

import { VERY_SHORT_TIMEOUT } from 'e2e/src/utils/timing.utils';

import { Page } from '../../classes/page.class';
import { createPageElement } from '../../utils/search.utils';

export class NotificationsListPage extends Page {
newNotification?: NotificationInterface;
notificationItem = createPageElement(PreviewItemSelectors.notificationItem);
notificationItemTitleText = createPageElement(PreviewItemSelectors.notificationItemTitleText);
notificationItemDescriptionText = createPageElement(PreviewItemSelectors.notificationItemDescriptionText);

async isVisible() {
await this.notificationItem.waitForDisplayed();
await this.notificationItemTitleText.waitForDisplayed();
await this.notificationItemDescriptionText.waitForDisplayed();
}

async isNotificationDisplayed({ id, title, description }: NotificationInterface) {
const notificationTextPageElem = createPageElement(PreviewItemSelectors.notificationItem, { id: String(id) });

await notificationTextPageElem.waitForDisplayed(
VERY_SHORT_TIMEOUT,
`Notification with ${title} title is not displayed`
);

const titleText = await notificationTextPageElem
.createChildElement(PreviewItemSelectors.notificationItemTitleText)
.getText();
if (titleText !== title) throw new Error(`Notification title missmatch. Got: ${titleText}`);

const descriptionText = await notificationTextPageElem
.createChildElement(PreviewItemSelectors.notificationItemDescriptionText)
.getText();
if (descriptionText !== description) throw new Error(`Notification description missmatch. Got: ${descriptionText}`);
}

async clickOnTheNotification({ id }: NotificationInterface) {
const notificationTextElem = createPageElement(PreviewItemSelectors.notificationItem, { id: String(id) });
await notificationTextElem.click();
}

async isNotificationNotDisplayed({ id, title }: NotificationInterface) {
const notificationTextElem = createPageElement(PreviewItemSelectors.notificationItem, { id: String(id) });

await notificationTextElem.waitForDisplayed(1_500).then(
() => {
throw new Error(`The notification '${title}' is displayed after turning off 'news' checkbox in settings`);
},
() => undefined
);
}
}
6 changes: 3 additions & 3 deletions e2e/src/step-definitions/common.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Given } from '@cucumber/cucumber';

import { BrowserContext } from '../classes/browser-context.class';
import { Pages } from '../page-objects';
import { iEnterValues, IEnterValuesKey } from '../utils/input-data.utils';
import { clearDataFromInput, createPageElement } from '../utils/search.utils';
import { iEnterValues, IEnterValuesKey, clearDataFromCurrentInput } from '../utils/input-data.utils';
import { createPageElement } from '../utils/search.utils';
import { LONG_TIMEOUT, MEDIUM_TIMEOUT, SHORT_TIMEOUT } from '../utils/timing.utils';

Given(/^I am on the (\w+) page$/, { timeout: LONG_TIMEOUT }, async (page: keyof typeof Pages) => {
Expand All @@ -20,7 +20,7 @@ Given(
async (elementName: string, pageName: string) => {
const element = createPageElement(`${pageName}/${elementName}`);
await element.click();
await clearDataFromInput();
await clearDataFromCurrentInput();
}
);

Expand Down
60 changes: 60 additions & 0 deletions e2e/src/step-definitions/notifications.steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Given } from '@cucumber/cucumber';
import assert from 'assert';
import axios from 'axios';
import type { NotificationInterface } from 'src/lib/notifications/types';

import { envVars } from 'e2e/src/utils/env.utils';
import { MEDIUM_TIMEOUT } from 'e2e/src/utils/timing.utils';

import { Pages } from '../page-objects';

Given(/I check that new notification is displayed/, { timeout: MEDIUM_TIMEOUT }, async () => {
const notification = Pages.NotificationsList.newNotification;
assert(notification);
await Pages.NotificationsList.isNotificationDisplayed(notification);
});

Given(/I check that new notification is NOT displayed/, { timeout: MEDIUM_TIMEOUT }, async () => {
const notification = Pages.NotificationsList.newNotification;
assert(notification);
await Pages.NotificationsList.isNotificationNotDisplayed(notification);
});

Given(/I click on the new notification/, { timeout: MEDIUM_TIMEOUT }, async () => {
const notification = Pages.NotificationsList.newNotification;
assert(notification);
await Pages.NotificationsList.clickOnTheNotification(notification);
});

Given(/I make request for creating a notification/, { timeout: MEDIUM_TIMEOUT }, async () => {
const currentDate = new Date();
const currentDateISO = currentDate.toISOString();
const expirationDateISO = new Date(currentDate.getTime() + 90000).toISOString(); // Notification will be deleted in 1.5 minute

const requestBody = {
mobile: 'off',
extension: 'on',
type: 'News',
title: 'Test Title',
description: 'Test description',
extensionImageUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRtIvsRFAUjlUKqlsLnrrJnWtcx98vOncHTXQ&usqp=CAU',
mobileImageUrl: '',
content: 'Test content',
date: currentDateISO,
expirationDate: expirationDateISO
};

const response = await axios.post<{ notification: NotificationInterface }>('/api/notifications', requestBody, {
baseURL: envVars.TEMPLE_WALLET_API_URL,
headers: {
'Content-Type': 'application/json',
Authorization: envVars.NOTIFICATION_AUTHORIZATION
}
});

if (response.status !== 200)
throw new Error(`Notifications request failed with ${response.status}: ${response.statusText}`);

Pages.NotificationsList.newNotification = response.data.notification;
});
6 changes: 3 additions & 3 deletions e2e/src/step-definitions/shared.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ Given(
/I got the validation-error '(.*)' in the (.*) on the (.*) page/,
{ timeout: MEDIUM_TIMEOUT },
async (errorName: string, parentElementName: string, pageName: string) => {
const childElement = await createPageElement(`${pageName}/${parentElementName}`).findChildSelectors(
ErrorCaptionSelectors.inputError
);
const childElement = await createPageElement(`${pageName}/${parentElementName}`)
.createChildElement(ErrorCaptionSelectors.inputError)
.findElement();
const getErrorContent = await getElementText(childElement);
expect(getErrorContent).eql(errorName);
}
Expand Down
3 changes: 2 additions & 1 deletion e2e/src/utils/browser.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const initBrowser = () =>
`--disable-extensions-except=${EXTENSION_PATH}`,
`--load-extension=${EXTENSION_PATH}`,
'--user-agent=E2EPipeline/0.0.1',
'--start-fullscreen'
'--start-fullscreen',
'--disable-notifications'
],
slowMo: 10
});
Expand Down
Loading
Loading