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

This commit is contained in:
Emily 2023-05-31 16:23:30 +10:00
parent 9e3a569fac
commit 75c42356c7
9 changed files with 74 additions and 97 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import { Page } from '@playwright/test';
import { User } from '../types/testing';
import { clickOnMatchingText, typeIntoInput } from '../utilities/utils';
import { checkPathLight, clickOnMatchingText, typeIntoInput } from '../utilities/utils';
// tslint:disable: no-console
export const newUser = async (window: Page, userName: string): Promise<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}`);
await window.click('.session-icon-button.small');
await checkPathLight(window);
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 };
// }

View file

@ -88,6 +88,31 @@ export async function waitForLoadingAnimationToFinish(
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
export async function clickOnElement(