feat: Adds id to the notifications and buttons so we can check for them in the integration tests.

This commit is contained in:
damencho 2020-07-10 10:28:57 -05:00 committed by Дамян Минков
parent 0cef706b6a
commit b106e51a10
8 changed files with 44 additions and 4 deletions

View File

@ -58,6 +58,11 @@ export type Props = {
*/
status?: ?string,
/**
* TestId of the element, if any.
*/
testId?: string,
/**
* URL of the avatar, if any.
*/
@ -122,6 +127,7 @@ class Avatar<P: Props> extends PureComponent<P, State> {
id,
size,
status,
testId,
url
} = this.props;
const { avatarFailed } = this.state;
@ -134,6 +140,7 @@ class Avatar<P: Props> extends PureComponent<P, State> {
onAvatarLoadError: undefined,
size,
status,
testId,
url: undefined
};

View File

@ -25,7 +25,12 @@ type Props = AbstractProps & {
/**
* One of the expected status strings (e.g. 'available') to render a badge on the avatar, if necessary.
*/
status?: ?string
status?: ?string,
/**
* TestId of the element, if any.
*/
testId?: string
};
/**
@ -45,6 +50,7 @@ export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
return (
<div
className = { `${this._getAvatarClassName()} ${this._getBadgeClassName()}` }
data-testid = { this.props.testId }
id = { this.props.id }
style = { this._getAvatarStyle(this.props.color) }>
<Icon
@ -59,6 +65,7 @@ export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
<div className = { this._getBadgeClassName() }>
<img
className = { this._getAvatarClassName() }
data-testid = { this.props.testId }
id = { this.props.id }
onError = { this.props.onAvatarLoadError }
src = { url }
@ -71,6 +78,7 @@ export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
return (
<div
className = { `${this._getAvatarClassName()} ${this._getBadgeClassName()}` }
data-testid = { this.props.testId }
id = { this.props.id }
style = { this._getAvatarStyle(this.props.color) }>
<svg
@ -97,6 +105,7 @@ export default class StatelessAvatar extends AbstractStatelessAvatar<Props> {
<div className = { this._getBadgeClassName() }>
<img
className = { this._getAvatarClassName('defaultAvatar') }
data-testid = { this.props.testId }
id = { this.props.id }
src = { this.props.defaultAvatar || 'images/avatar.png' }
style = { this._getAvatarStyle() } />

View File

@ -26,6 +26,11 @@ type Props = {
*/
hasOptions?: boolean,
/**
* TestId of the button. Can be used to locate element when testing UI.
*/
testId?: string,
/**
* The type of th button: primary, secondary, text.
*/
@ -52,6 +57,7 @@ function ActionButton({
className = '',
disabled,
hasOptions,
testId,
type = 'primary',
onClick,
onOptionsClick
@ -59,6 +65,7 @@ function ActionButton({
return (
<div
className = { `action-btn ${className} ${type} ${disabled ? 'disabled' : ''}` }
data-testid = { testId ? testId : undefined }
onClick = { disabled ? undefined : onClick }>
{children}
{hasOptions && <div

View File

@ -11,6 +11,11 @@ type Props = {
*/
className?: string,
/**
* TestId of the button. Can be used to locate element when testing UI.
*/
testId?: string,
/**
* Callback for the onChange event of the field.
*/
@ -105,6 +110,7 @@ export default class InputField extends PureComponent<Props, State> {
return (
<input
className = { `field ${this.state.focused ? 'focused' : ''} ${this.props.className || ''}` }
data-testid = { this.props.testId ? this.props.testId : undefined }
onBlur = { this._onBlur }
onChange = { this._onChange }
onFocus = { this._onFocus }

View File

@ -48,25 +48,28 @@ class KnockingParticipantList extends AbstractKnockingParticipantList<Props> {
<Avatar
displayName = { p.name }
size = { 48 }
testId = 'knockingParticipant.avatar'
url = { p.loadableAvatarUrl } />
<div className = 'details'>
<span>
<span data-testid = 'knockingParticipant.name'>
{ p.name }
</span>
{ p.email && (
<span>
<span data-testid = 'knockingParticipant.email'>
{ p.email }
</span>
) }
</div>
<button
className = 'primary'
data-testid = 'lobby.allow'
onClick = { this._onRespondToParticipant(p.id, true) }
type = 'button'>
{ t('lobby.allow') }
</button>
<button
className = 'borderLess'
data-testid = 'lobby.reject'
onClick = { this._onRespondToParticipant(p.id, false) }
type = 'button'>
{ t('lobby.reject') }

View File

@ -97,6 +97,7 @@ class LobbyScreen extends AbstractLobbyScreen {
<InputField
onChange = { this._onChangeDisplayName }
placeHolder = { t('lobby.nameField') }
testId = 'lobby.nameField'
value = { displayName } />
</div>
</div>
@ -117,6 +118,7 @@ class LobbyScreen extends AbstractLobbyScreen {
className = { _passwordJoinFailed ? 'error' : '' }
onChange = { this._onChangePassword }
placeHolder = { _passwordJoinFailed ? t('lobby.invalidPassword') : t('lobby.passwordField') }
testId = 'lobby.password'
type = 'password'
value = { this.state.password } />
</div>
@ -136,11 +138,13 @@ class LobbyScreen extends AbstractLobbyScreen {
<ActionButton
disabled = { !this.state.password }
onClick = { this._onJoinWithPassword }
testId = 'lobby.passwordJoinButton'
type = 'primary'>
{ t('lobby.passwordJoinButton') }
</ActionButton>
<ActionButton
onClick = { this._onSwitchToKnockMode }
testId = 'lobby.backToKnockModeButton'
type = 'secondary'>
{ t('lobby.backToKnockModeButton') }
</ActionButton>
@ -161,11 +165,13 @@ class LobbyScreen extends AbstractLobbyScreen {
{ _knocking || <ActionButton
disabled = { !this.state.displayName }
onClick = { this._onAskToJoin }
testId = 'lobby.knockButton'
type = 'primary'>
{ t('lobby.knockButton') }
</ActionButton> }
<ActionButton
onClick = { this._onSwitchToPasswordMode }
testId = 'lobby.enterPasswordButton'
type = 'secondary'>
{ t('lobby.enterPasswordButton') }
</ActionButton>

View File

@ -62,6 +62,7 @@ class Notification extends AbstractNotification<Props> {
id = { uid }
isDismissAllowed = { isDismissAllowed }
onDismissed = { onDismissed }
testId = { titleKey }
title = { title || t(titleKey, titleArguments) } />
);
}
@ -84,7 +85,7 @@ class Notification extends AbstractNotification<Props> {
// the id is used for testing the UI
return (
<div id = { this._getDescriptionKey() || description || this.props.titleKey || this.props.title } >
<div data-testid = { this._getDescriptionKey() } >
{ description }
</div>
);

View File

@ -313,6 +313,7 @@ class Prejoin extends Component<Props, State> {
hasOptions = { true }
onClick = { joinConference }
onOptionsClick = { _onOptionsClick }
testId = 'prejoin.joinMeeting'
type = 'primary'>
{ t('prejoin.joinMeeting') }
</ActionButton>