Adding in data test-id to path light and fixing disappearing messages test

pull/2786/head
Emily 2 years ago
parent 9e3a569fac
commit 75c42356c7

@ -26,6 +26,7 @@ export type StatusLightType = {
glowStartDelay: number; glowStartDelay: number;
glowDuration: number; glowDuration: number;
color?: string; color?: string;
dataTestId?: string
}; };
const StyledCountry = styled.div` const StyledCountry = styled.div`
@ -143,19 +144,21 @@ const OnionPathModalInner = () => {
export type OnionNodeStatusLightType = { export type OnionNodeStatusLightType = {
glowStartDelay: number; glowStartDelay: number;
glowDuration: number; glowDuration: number;
dataTestId?: string
}; };
/** /**
* Component containing a coloured status light. * Component containing a coloured status light.
*/ */
export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Element => { export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Element => {
const { glowStartDelay, glowDuration } = props; const { glowStartDelay, glowDuration, dataTestId } = props;
return ( return (
<ModalStatusLight <ModalStatusLight
glowDuration={glowDuration} glowDuration={glowDuration}
glowStartDelay={glowStartDelay} glowStartDelay={glowStartDelay}
color={'var(--button-path-default-color)'} color={'var(--button-path-default-color)'}
dataTestId={dataTestId}
/> />
); );
}; };
@ -186,10 +189,9 @@ export const ModalStatusLight = (props: StatusLightType) => {
export const ActionPanelOnionStatusLight = (props: { export const ActionPanelOnionStatusLight = (props: {
isSelected: boolean; isSelected: boolean;
handleClick: () => void; handleClick: () => void;
dataTestId?: string;
id: string; id: string;
}) => { }) => {
const { isSelected, handleClick, dataTestId, id } = props; const { isSelected, handleClick, id } = props;
const onionPathsCount = useSelector(getOnionPathsCount); const onionPathsCount = useSelector(getOnionPathsCount);
const firstPathLength = useSelector(getFirstOnionPathLength); const firstPathLength = useSelector(getFirstOnionPathLength);
@ -218,7 +220,8 @@ export const ActionPanelOnionStatusLight = (props: {
glowStartDelay={0} glowStartDelay={0}
noScale={true} noScale={true}
isSelected={isSelected} isSelected={isSelected}
dataTestId={dataTestId} dataTestId={"path-light-container"}
dataTestIdIcon={"path-light-svg"}
id={id} id={id}
/> />
); );

@ -14,6 +14,7 @@ export type SessionIconProps = {
glowStartDelay?: number; glowStartDelay?: number;
noScale?: boolean; noScale?: boolean;
backgroundColor?: string; backgroundColor?: string;
dataTestId?: string
}; };
const getIconDimensionFromIconSize = (iconSize: SessionIconSize | number) => { const getIconDimensionFromIconSize = (iconSize: SessionIconSize | number) => {
@ -122,7 +123,7 @@ const animation = (props: {
}; };
//tslint:disable no-unnecessary-callback-wrapper //tslint:disable no-unnecessary-callback-wrapper
const Svg = React.memo(styled.svg<StyledSvgProps>` const Svg = styled.svg<StyledSvgProps>`
width: ${props => props.width}; width: ${props => props.width};
transform: ${props => `rotate(${props.iconRotation}deg)`}; transform: ${props => `rotate(${props.iconRotation}deg)`};
animation: ${props => animation(props)}; animation: ${props => animation(props)};
@ -134,7 +135,7 @@ const Svg = React.memo(styled.svg<StyledSvgProps>`
fill: ${props => (props.iconColor ? props.iconColor : '--button-icon-stroke-color')}; fill: ${props => (props.iconColor ? props.iconColor : '--button-icon-stroke-color')};
padding: ${props => (props.iconPadding ? props.iconPadding : '')}; padding: ${props => (props.iconPadding ? props.iconPadding : '')};
transition: inherit; transition: inherit;
`); `;
// tslint:enable no-unnecessary-callback-wrapper // tslint:enable no-unnecessary-callback-wrapper
const SessionSvg = (props: { const SessionSvg = (props: {
@ -151,6 +152,7 @@ const SessionSvg = (props: {
borderRadius?: string; borderRadius?: string;
backgroundColor?: string; backgroundColor?: string;
iconPadding?: string; iconPadding?: string;
dataTestId?: string
}) => { }) => {
const colorSvg = props.iconColor ? props.iconColor : '--button-icon-stroke-color'; const colorSvg = props.iconColor ? props.iconColor : '--button-icon-stroke-color';
const pathArray = props.path instanceof Array ? props.path : [props.path]; const pathArray = props.path instanceof Array ? props.path : [props.path];
@ -167,10 +169,11 @@ const SessionSvg = (props: {
backgroundColor: props.backgroundColor, backgroundColor: props.backgroundColor,
borderRadius: props.borderRadius, borderRadius: props.borderRadius,
iconPadding: props.iconPadding, iconPadding: props.iconPadding,
dataTestId: props.dataTestId
}; };
return ( return (
<Svg {...propsToPick}> <Svg data-testid={props.dataTestId} {...propsToPick}>
{pathArray.map((path, index) => { {pathArray.map((path, index) => {
return <path key={index} fill={colorSvg} d={path} />; return <path key={index} fill={colorSvg} d={path} />;
})} })}
@ -189,6 +192,8 @@ export const SessionIcon = (props: SessionIconProps) => {
noScale, noScale,
backgroundColor, backgroundColor,
iconPadding, iconPadding,
dataTestId
} = props; } = props;
let { iconSize, iconRotation } = props; let { iconSize, iconRotation } = props;
iconSize = iconSize || 'medium'; iconSize = iconSize || 'medium';
@ -197,6 +202,9 @@ export const SessionIcon = (props: SessionIconProps) => {
const iconDimensions = getIconDimensionFromIconSize(iconSize); const iconDimensions = getIconDimensionFromIconSize(iconSize);
const iconDef = icons[iconType]; const iconDef = icons[iconType];
const ratio = iconDef?.ratio || 1; const ratio = iconDef?.ratio || 1;
if(iconType === 'circle') {
console.warn("props",props)
}
return ( return (
<SessionSvg <SessionSvg
@ -213,6 +221,7 @@ export const SessionIcon = (props: SessionIconProps) => {
iconColor={iconColor} iconColor={iconColor}
backgroundColor={backgroundColor} backgroundColor={backgroundColor}
iconPadding={iconPadding} iconPadding={iconPadding}
dataTestId={dataTestId}
/> />
); );
}; };

@ -12,6 +12,7 @@ interface SProps extends SessionIconProps {
isHidden?: boolean; isHidden?: boolean;
margin?: string; margin?: string;
dataTestId?: string; dataTestId?: string;
dataTestIdIcon?: string;
id?: string; id?: string;
style?: object; style?: object;
} }
@ -54,6 +55,7 @@ const SessionIconButtonInner = React.forwardRef<HTMLDivElement, SProps>((props,
margin, margin,
id, id,
dataTestId, dataTestId,
dataTestIdIcon,
style, style,
} = props; } = props;
const clickHandler = (e: React.MouseEvent<HTMLDivElement>) => { const clickHandler = (e: React.MouseEvent<HTMLDivElement>) => {
@ -86,7 +88,7 @@ const SessionIconButtonInner = React.forwardRef<HTMLDivElement, SProps>((props,
backgroundColor={backgroundColor} backgroundColor={backgroundColor}
borderRadius={borderRadius} borderRadius={borderRadius}
iconPadding={iconPadding} iconPadding={iconPadding}
data-testid={dataTestId} dataTestId={dataTestIdIcon}
/> />
{Boolean(notificationCount) && <SessionNotificationCount count={notificationCount} />} {Boolean(notificationCount) && <SessionNotificationCount count={notificationCount} />}
</StyledSessionIconButton> </StyledSessionIconButton>

@ -124,7 +124,6 @@ const Section = (props: { type: SectionType }) => {
case SectionType.PathIndicator: case SectionType.PathIndicator:
return ( return (
<ActionPanelOnionStatusLight <ActionPanelOnionStatusLight
dataTestId="onion-status-section"
handleClick={handleClick} handleClick={handleClick}
isSelected={isSelected} isSelected={isSelected}
id={'onion-path-indicator-led-id'} id={'onion-path-indicator-led-id'}

@ -1,6 +1,6 @@
import { Data, Snode } from '../../../ts/data/data'; import { Data, Snode } from '../../../ts/data/data';
import * as SnodePool from '../apis/snode_api/snodePool'; import * as SnodePool from '../apis/snode_api/snodePool';
import _ from 'lodash'; import _, { compact } from 'lodash';
import { default as insecureNodeFetch } from 'node-fetch'; import { default as insecureNodeFetch } from 'node-fetch';
import { UserUtils } from '../utils'; import { UserUtils } from '../utils';
import { Onions, snodeHttpsAgent } from '../apis/snode_api/onions'; import { Onions, snodeHttpsAgent } from '../apis/snode_api/onions';
@ -150,6 +150,7 @@ export async function getOnionPath({ toExclude }: { toExclude?: Snode }): Promis
throw new Error(`Failed to build enough onion paths, current count: ${onionPaths.length}`); throw new Error(`Failed to build enough onion paths, current count: ${onionPaths.length}`);
} }
} }
onionPaths = onionPaths.map(compact)
if (onionPaths.length === 0) { if (onionPaths.length === 0) {
if (!_.isEmpty(window.inboxStore?.getState().onionPaths.snodePaths)) { if (!_.isEmpty(window.inboxStore?.getState().onionPaths.snodePaths)) {
@ -182,6 +183,7 @@ export async function getOnionPath({ toExclude }: { toExclude?: Snode }): Promis
const onionPathsWithoutExcluded = onionPaths.filter( const onionPathsWithoutExcluded = onionPaths.filter(
path => !_.some(path, node => node.pubkey_ed25519 === toExclude.pubkey_ed25519) path => !_.some(path, node => node.pubkey_ed25519 === toExclude.pubkey_ed25519)
); );
if (!onionPathsWithoutExcluded || onionPathsWithoutExcluded.length === 0) { if (!onionPathsWithoutExcluded || onionPathsWithoutExcluded.length === 0) {
throw new Error('No onion paths available after filtering'); throw new Error('No onion paths available after filtering');
} }

@ -6,7 +6,7 @@ import { openAppAndWait } from './setup/open';
import { import {
clickOnMatchingText, clickOnMatchingText,
clickOnTestIdWithText, clickOnTestIdWithText,
waitForTestIdWithText, waitForTestIdWithText
} from './utilities/utils'; } from './utilities/utils';
let window: Page | undefined; let window: Page | undefined;

@ -4,14 +4,13 @@ import { beforeAllClean } from './setup/beforeEach';
import { newUser } from './setup/new_user'; import { newUser } from './setup/new_user';
import { openApp } from './setup/open'; import { openApp } from './setup/open';
import { sendMessage } from './utilities/message'; import { sendMessage } from './utilities/message';
import { sendNewMessage } from './utilities/send_message';
import { import {
clickOnMatchingText, clickOnMatchingText,
clickOnTestIdWithText, clickOnTestIdWithText,
waitForControlMessageWithText, hasTextElementBeenDeleted,
waitForMatchingText,
waitForTestIdWithText, waitForTestIdWithText,
} from './utilities/utils'; } from './utilities/utils';
import { createContact } from './utilities/create_contact';
test.beforeEach(beforeAllClean); test.beforeEach(beforeAllClean);
@ -19,9 +18,9 @@ test.beforeEach(beforeAllClean);
// tslint:disable: no-console // tslint:disable: no-console
const testMessage = 'Test-Message- (A -> B) '; const testMessage = 'Test-Message- (A -> B) ';
const testReply = 'Reply-Test-Message- (B -> A)'; // const testReply = 'Reply-Test-Message- (B -> A)';
const sentMessage = `${testMessage}${Date.now()}`; const sentMessage = `${testMessage}${Date.now()}`;
const sentReplyMessage = `${testReply} :${Date.now()}`; // const sentReplyMessage = `${testReply} :${Date.now()}`;
test('Disappearing messages', async () => { test('Disappearing messages', async () => {
// Open App // Open App
@ -29,11 +28,9 @@ test('Disappearing messages', async () => {
const [windowA, windowB] = await openApp(2); const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
// Create Contact // Create Contact
await sendNewMessage(windowA, userB.sessionid, sentMessage); await createContact(windowA, windowB, userA, userB);
await sendNewMessage(windowB, userA.sessionid, sentReplyMessage); // Need to wait for contact approval
await waitForControlMessageWithText(windowA, 'Your message request has been accepted'); await sleepFor(5000);
// await waitForMatchingText(windowA, `You have accepted ${userA.userName}'s message request`);
// await waitForMatchingText(windowB, 'Your message request has been accepted');
// Click on user's avatar to open conversation options // Click on user's avatar to open conversation options
await clickOnTestIdWithText(windowA, 'conversation-options-avatar'); await clickOnTestIdWithText(windowA, 'conversation-options-avatar');
// Select disappearing messages drop down // Select disappearing messages drop down
@ -48,57 +45,21 @@ test('Disappearing messages', async () => {
'control-message', 'control-message',
'You set the disappearing message timer to 5 seconds' 'You set the disappearing message timer to 5 seconds'
); );
await sleepFor(2000); await waitForTestIdWithText(
windowB,
'control-message',
`${userA.userName} set the disappearing message timer to 5 seconds`
);
await sleepFor(500);
// Check top right hand corner indicator // Check top right hand corner indicator
await waitForTestIdWithText(windowA, 'disappearing-messages-indicator', '5 seconds'); await waitForTestIdWithText(windowA, 'disappearing-messages-indicator', '5 seconds');
// Send message // Send message
// Wait for tick of confirmation
await sendMessage(windowA, sentMessage); await sendMessage(windowA, sentMessage);
// Check timer is functioning // Check timer is functioning
await sleepFor(6000);
// Verify message is deleted // Verify message is deleted
const errorDesc = 'Should not be found'; await hasTextElementBeenDeleted(windowA, sentMessage, 3000);
try { // focus window B
const elemShouldNotBeFound = windowA.locator(sentMessage); await clickOnTestIdWithText(windowB, "control-message", `${userA.userName} set the disappearing message timer to 5 seconds`);
if (elemShouldNotBeFound) { await hasTextElementBeenDeleted(windowB, sentMessage, 4000);
console.error('Sent message not found in window A');
throw new Error(errorDesc);
}
} catch (e) {
if (e.message !== errorDesc) {
throw e;
}
}
// Click on user's avatar for options
await clickOnTestIdWithText(windowA, 'conversation-options-avatar');
// Click on disappearing messages drop down
await clickOnMatchingText(windowA, 'Disappearing messages');
// Select off
await clickOnMatchingText(windowA, 'Off');
// Click chevron to close menu
await clickOnTestIdWithText(windowA, 'back-button-conversation-options');
// Check config message
await waitForTestIdWithText(windowA, 'control-message', 'You disabled disappearing messages.');
// Verify message is deleted in windowB for receiver user
// Check config message in windowB
await waitForMatchingText(
windowB,
`${userA.userName} set the disappearing message timer to 5 seconds`
);
// Wait 5 seconds
await waitForMatchingText(windowB, `${userA.userName} has turned off disappearing messages.`);
// verify message is deleted in windowB
const errorDesc2 = 'Should not be found';
try {
const elemShouldNotBeFound = windowA.locator(sentMessage);
if (elemShouldNotBeFound) {
console.error('Sent message not found in window B');
throw new Error(errorDesc2);
}
} catch (e) {
if (e.message !== errorDesc2) {
throw e;
}
}
}); });

@ -1,6 +1,6 @@
import { Page } from '@playwright/test'; import { Page } from '@playwright/test';
import { User } from '../types/testing'; import { User } from '../types/testing';
import { clickOnMatchingText, typeIntoInput } from '../utilities/utils'; import { checkPathLight, clickOnMatchingText, typeIntoInput } from '../utilities/utils';
// tslint:disable: no-console // tslint:disable: no-console
export const newUser = async (window: Page, userName: string): Promise<User> => { export const newUser = async (window: Page, userName: string): Promise<User> => {
// Create User // Create User
@ -19,32 +19,8 @@ export const newUser = async (window: Page, userName: string): Promise<User> =>
console.info(`${userName}: Session ID: ${sessionid} and Recovery phrase: ${recoveryPhrase}`); console.info(`${userName}: Session ID: ${sessionid} and Recovery phrase: ${recoveryPhrase}`);
await window.click('.session-icon-button.small'); await window.click('.session-icon-button.small');
await checkPathLight(window);
return { userName, sessionid, recoveryPhrase }; return { userName, sessionid, recoveryPhrase };
}; };
// const openAppAndNewUser = async (multi: string): Promise<User & { window: Page }> => {
// const window = await openAppAndWait(multi);
// const userName = `${multi}-user`;
// const loggedIn = await newUser(window, userName);
// return { window, ...loggedIn };
// };
// export async function openAppsAndNewUsers(windowToCreate: number) {
// if (windowToCreate >= multisAvailable.length) {
// throw new Error(`Do you really need ${multisAvailable.length} windows?!`);
// }
// // if windowToCreate = 3, this array will be ABC. If windowToCreate = 5, this array will be ABCDE
// const multisToUse = multisAvailable.slice(0, windowToCreate);
// const loggedInDetails = await Promise.all(
// [...multisToUse].map(async m => {
// return openAppAndNewUser(m);
// })
// );
// const windows = loggedInDetails.map(w => w.window);
// const users = loggedInDetails.map(w => {
// return _.pick(w, ['sessionid', 'recoveryPhrase', 'userName']);
// });
// return { windows, users };
// }

@ -88,6 +88,31 @@ export async function waitForLoadingAnimationToFinish(
console.info('Loading animation has finished'); console.info('Loading animation has finished');
} }
export async function checkPathLight(window: Page, maxWait?: number) {
let pathLight: ElementHandle<SVGElement | HTMLElement> | undefined;
const maxWaitTime = maxWait || 100000;
const waitPerLoop = 100;
let start = Date.now();
pathLight = await waitForElement(window, 'data-testid', "path-light-container", maxWait);
let pathColor = await pathLight.getAttribute('color');
while(pathColor === 'var(--button-path-error-color)') {
await sleepFor(waitPerLoop)
pathLight = await waitForElement(window, 'data-testid', "path-light-container", maxWait);
pathColor = await pathLight.getAttribute('color');
start += waitPerLoop
if(Date.now() - start >= (maxWaitTime / 2)) {
console.log('Path building...')
}
if(Date.now() - start >= maxWaitTime) {
throw new Error('Timed out waiting for path')
}
}
console.log('Path built correctly, Yay!', pathColor)
}
// ACTIONS // ACTIONS
export async function clickOnElement( export async function clickOnElement(

Loading…
Cancel
Save