Add stateful buttons on forms (#37)

Add stateful button component from paragon to
- LoginPage
- RegistrationPage
- ForgetPasswordPage
- ResetPasswordPage

VAN-123
This commit is contained in:
Zainab Amir
2020-11-27 15:22:41 +05:00
committed by GitHub
parent 7e4d990ade
commit 71885b6fd2
15 changed files with 2179 additions and 162 deletions

View File

@@ -6,3 +6,7 @@ export const DEFAULT_REDIRECT_URL = '/dashboard';
// Constants
export const SUPPORTED_ICON_CLASSES = ['apple', 'facebook', 'google', 'microsoft'];
// Stateful Submit Button States
export const DEFAULT_STATE = 'default';
export const PENDING_STATE = 'pending';

View File

@@ -2,13 +2,14 @@ import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { Button, Input, ValidationFormGroup } from '@edx/paragon';
import { Input, StatefulButton, ValidationFormGroup } from '@edx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from './messages';
import { forgotPassword } from './data/actions';
import { forgotPasswordResultSelector } from './data/selectors';
import RequestInProgressAlert from './RequestInProgressAlert';
import { LOGIN_PAGE } from '../data/constants';
import LoginHelpLinks from '../logistration/LoginHelpLinks';
const ForgotPasswordPage = (props) => {
@@ -39,7 +40,7 @@ const ForgotPasswordPage = (props) => {
return (
<>
{status === 'complete' ? <Redirect to="/login" /> : null}
{status === 'complete' ? <Redirect to={LOGIN_PAGE} /> : null}
<div className="d-flex justify-content-center forgot-password-container">
<div className="d-flex flex-column" style={{ width: '450px' }}>
<form className="m-4">
@@ -79,12 +80,15 @@ const ForgotPasswordPage = (props) => {
</p>
<LoginHelpLinks page="forgot-password" />
</div>
<Button
<StatefulButton
type="submit"
className="btn-primary submit"
state={status}
labels={{
default: intl.formatMessage(messages['logisration.forgot.password.page.submit.button']),
}}
onClick={e => handleSubmit(e)}
>
{intl.formatMessage(messages['logisration.forgot.password.page.submit.button'])}
</Button>
/>
</form>
</div>
</div>

View File

@@ -49,6 +49,16 @@ describe('ForgotPasswordPage', () => {
expect(tree).toMatchSnapshot();
});
it('should match pending section snapshot', () => {
props = {
...props,
status: 'pending',
};
const tree = renderer.create(reduxWrapper(<IntlForgotPasswordPage {...props} />))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('should match success section snapshot', () => {
props = {
...props,

View File

@@ -110,12 +110,18 @@ exports[`ForgotPasswordPage should match default section snapshot 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-null btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Recover my password
<span
className="d-flex align-items-center justify-content-center"
>
Recover my password
</span>
</button>
</form>
</div>
@@ -260,12 +266,155 @@ exports[`ForgotPasswordPage should match forbidden section snapshot 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-forbidden btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Recover my password
<span
className="d-flex align-items-center justify-content-center"
>
Recover my password
</span>
</button>
</form>
</div>
</div>
`;
exports[`ForgotPasswordPage should match pending section snapshot 1`] = `
<div
className="d-flex justify-content-center forgot-password-container"
>
<div
className="d-flex flex-column"
style={
Object {
"width": "450px",
}
}
>
<form
className="m-4"
>
<div
className="form-group"
>
<h3
className="text-center mt-3"
>
Password assistance
</h3>
<p
className="mb-4"
>
Please enter your log-in or recovery email address below and we will send you an email with instructions.
</p>
<div
className="d-flex flex-column align-items-start"
>
<div
className="form-group mb-0"
>
<label
className="h6 mr-1"
htmlFor="forgot-password-input"
>
Email
</label>
<input
aria-describedby=""
className="form-control"
id="forgot-password-input"
name="email"
onChange={[Function]}
placeholder="username@domain.com"
style={
Object {
"width": "400px",
}
}
type="email"
value=""
/>
<strong
className="invalid-feedback"
id="email-invalid-feedback"
>
The email address you've provided isn't formatted correctly.
</strong>
</div>
</div>
<p
className="mb-2"
>
The email address you used to register with edX.
</p>
<button
className="mt-1 field-link"
onClick={[Function]}
type="button"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-caret-right fa-w-6 mr-1"
data-icon="caret-right"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 192 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
fill="currentColor"
style={Object {}}
/>
</svg>
Need other help signing in?
</button>
<div
className="pgn-transition-replace-group position-relative"
style={
Object {
"height": null,
}
}
>
<div
style={
Object {
"padding": ".1px 0",
}
}
/>
</div>
</div>
<button
aria-disabled={true}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-pending btn-primary submit disabled btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
>
<span
className="d-flex align-items-center justify-content-center"
>
<span
className="pgn__stateful-btn-icon"
>
<span
aria-hidden={true}
className="icon fa fa-spinner fa-spin"
id="Icon1"
/>
</span>
Recover my password
</span>
</button>
</form>
</div>

View File

@@ -1,22 +1,23 @@
import React from 'react';
import { Button, Input, ValidationFormGroup } from '@edx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Input, StatefulButton, ValidationFormGroup } from '@edx/paragon';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { forgotPasswordResultSelector } from '../forgot-password';
import ConfirmationAlert from './ConfirmationAlert';
import { getThirdPartyAuthContext, loginRequest } from './data/actions';
import { DEFAULT_REDIRECT_URL, REGISTER_PAGE } from '../data/constants';
import { loginRequestSelector, thirdPartyAuthContextSelector } from './data/selectors';
import InstitutionLogistration, { RenderInstitutionButton } from './InstitutionLogistration';
import LoginHelpLinks from './LoginHelpLinks';
import LoginFailureMessage from './LoginFailure';
import messages from './messages';
import RedirectLogistration from './RedirectLogistration';
import SocialAuthProviders from './SocialAuthProviders';
import ThirdPartyAuthAlert from './ThirdPartyAuthAlert';
import InstitutionLogistration, { RenderInstitutionButton } from './InstitutionLogistration';
import messages from './messages';
import { DEFAULT_REDIRECT_URL, DEFAULT_STATE, REGISTER_PAGE } from '../data/constants';
import { forgotPasswordResultSelector } from '../forgot-password';
class LoginPage extends React.Component {
constructor(props, context) {
@@ -111,13 +112,13 @@ class LoginPage extends React.Component {
}
render() {
const { intl } = this.props;
const { currentProvider, finishAuthUrl, providers } = this.props.thirdPartyAuthContext;
const { intl, submitState, thirdPartyAuthContext } = this.props;
if (this.state.institutionLogin) {
return (
<InstitutionLogistration
onSubmitHandler={this.handleInstitutionLogin}
secondaryProviders={this.props.thirdPartyAuthContext.secondaryProviders}
secondaryProviders={thirdPartyAuthContext.secondaryProviders}
headingTitle={intl.formatMessage(messages['logistration.login.institution.login.page.title'])}
buttonTitle={intl.formatMessage(messages['logistration.login.institution.login.page.back.button'])}
/>
@@ -128,15 +129,15 @@ class LoginPage extends React.Component {
<RedirectLogistration
success={this.props.loginResult.success}
redirectUrl={this.props.loginResult.redirectUrl}
finishAuthUrl={finishAuthUrl}
finishAuthUrl={thirdPartyAuthContext.finishAuthUrl}
/>
<div className="d-flex justify-content-center login-container">
<div className="d-flex flex-column" style={{ width: '400px' }}>
{currentProvider
{thirdPartyAuthContext.currentProvider
&& (
<ThirdPartyAuthAlert
currentProvider={currentProvider}
platformName={this.props.thirdPartyAuthContext.platformName}
currentProvider={thirdPartyAuthContext.currentProvider}
platformName={thirdPartyAuthContext.platformName}
/>
)}
{this.props.loginError ? <LoginFailureMessage errors={this.props.loginError} /> : null}
@@ -146,15 +147,21 @@ class LoginPage extends React.Component {
First time here?<a className="ml-1" href={REGISTER_PAGE}>Create an Account.</a>
</p>
</div>
<h3 className="text-left mt-3">{intl.formatMessage(messages['logistration.login.institution.login.sign.in'])}</h3>
<RenderInstitutionButton
onSubmitHandler={this.handleInstitutionLogin}
secondaryProviders={this.props.thirdPartyAuthContext.secondaryProviders}
buttonTitle={intl.formatMessage(messages['logistration.login.institution.login.button'])}
/>
<div className="section-heading-line mb-4">
<h4>{intl.formatMessage(messages['logistration.login.institution.login.sign.in.with'])}</h4>
</div>
<h2 className="font-color text-left mt-2 mb-3">
{intl.formatMessage(messages['logistration.login.institution.login.sign.in'])}
</h2>
{thirdPartyAuthContext.secondaryProviders.length ? (
<>
<RenderInstitutionButton
onSubmitHandler={this.handleInstitutionLogin}
secondaryProviders={thirdPartyAuthContext.secondaryProviders}
buttonTitle={intl.formatMessage(messages['logistration.login.institution.login.button'])}
/>
<div className="section-heading-line mb-4">
<h4>{intl.formatMessage(messages['logistration.login.institution.login.sign.in.with'])}</h4>
</div>
</>
) : null }
<form className="m-0">
<div className="form-group">
<div className="d-flex flex-column align-items-start">
@@ -196,20 +203,23 @@ class LoginPage extends React.Component {
</div>
<LoginHelpLinks page="login" />
</div>
<Button
<StatefulButton
type="submit"
className="btn-primary submit"
state={submitState}
labels={{
default: intl.formatMessage(messages['logistration.sign.in.button']),
}}
onClick={this.handleSubmit}
>
Sign in
</Button>
/>
</form>
{providers.length && !currentProvider ? (
{thirdPartyAuthContext.providers.length && !thirdPartyAuthContext.currentProvider ? (
<>
<div className="section-heading-line mb-4">
<h4>or sign in with</h4>
</div>
<div className="row tpa-container">
<SocialAuthProviders socialAuthProviders={providers} />
<SocialAuthProviders socialAuthProviders={thirdPartyAuthContext.providers} />
</div>
</>
) : null}
@@ -221,28 +231,32 @@ class LoginPage extends React.Component {
}
LoginPage.defaultProps = {
loginResult: null,
forgotPassword: null,
loginResult: null,
loginError: null,
submitState: DEFAULT_STATE,
thirdPartyAuthContext: {
currentProvider: null,
finishAuthUrl: null,
providers: [],
secondaryProviders: [],
},
};
LoginPage.propTypes = {
intl: intlShape.isRequired,
forgotPassword: PropTypes.shape({
email: PropTypes.string,
status: PropTypes.string,
}),
getThirdPartyAuthContext: PropTypes.func.isRequired,
intl: intlShape.isRequired,
loginError: PropTypes.string,
loginRequest: PropTypes.func.isRequired,
loginResult: PropTypes.shape({
redirectUrl: PropTypes.string,
success: PropTypes.bool,
}),
forgotPassword: PropTypes.shape({
email: PropTypes.string,
status: PropTypes.string,
}),
submitState: PropTypes.string,
thirdPartyAuthContext: PropTypes.shape({
currentProvider: PropTypes.string,
platformName: PropTypes.string,
@@ -250,7 +264,6 @@ LoginPage.propTypes = {
secondaryProviders: PropTypes.array,
finishAuthUrl: PropTypes.string,
}),
loginError: PropTypes.string,
};
const mapStateToProps = state => {
@@ -258,10 +271,11 @@ const mapStateToProps = state => {
const loginResult = loginRequestSelector(state);
const thirdPartyAuthContext = thirdPartyAuthContextSelector(state);
return {
loginError: state.logistration.loginError,
submitState: state.logistration.submitState,
forgotPassword,
loginResult,
thirdPartyAuthContext,
loginError: state.logistration.loginError,
};
};

View File

@@ -1,9 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import {
Button, Input, ValidationFormGroup,
} from '@edx/paragon';
import { Input, StatefulButton, ValidationFormGroup } from '@edx/paragon';
import {
getLocale, getCountryList, injectIntl, intlShape,
} from '@edx/frontend-platform/i18n';
@@ -12,7 +10,9 @@ import { getThirdPartyAuthContext, registerNewUser } from './data/actions';
import { registrationRequestSelector, thirdPartyAuthContextSelector } from './data/selectors';
import RedirectLogistration from './RedirectLogistration';
import RegistrationFailure from './RegistrationFailure';
import { DEFAULT_REDIRECT_URL, LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
import {
DEFAULT_REDIRECT_URL, DEFAULT_STATE, LOGIN_PAGE, REGISTER_PAGE,
} from '../data/constants';
import SocialAuthProviders from './SocialAuthProviders';
import ThirdPartyAuthAlert from './ThirdPartyAuthAlert';
import InstitutionLogistration, { RenderInstitutionButton } from './InstitutionLogistration';
@@ -159,7 +159,7 @@ class RegistrationPage extends React.Component {
}
render() {
const { intl } = this.props;
const { intl, submitState } = this.props;
const {
currentProvider, finishAuthUrl, providers, secondaryProviders,
} = this.props.thirdPartyAuthContext;
@@ -295,12 +295,15 @@ class RegistrationPage extends React.Component {
/>
</ValidationFormGroup>
<span>By creating an account, you agree to the <a href="https://www.edx.org/edx-terms-service">Terms of Service and Honor Code</a> and you acknowledge that edX and each Member process your personal data in accordance with the <a href="https://www.edx.org/edx-privacy-policy">Privacy Policy</a>.</span>
<Button
className="btn-primary mt-4 submit"
<StatefulButton
type="submit"
className="btn-primary submit mt-4"
state={submitState}
labels={{
default: intl.formatMessage(messages['logistration.create.account.button']),
}}
onClick={this.handleSubmit}
>
Create Account
</Button>
/>
</form>
</div>
</>
@@ -312,6 +315,7 @@ RegistrationPage.defaultProps = {
registrationResult: null,
registerNewUser: null,
registrationError: null,
submitState: DEFAULT_STATE,
thirdPartyAuthContext: {
currentProvider: null,
finishAuthUrl: null,
@@ -333,6 +337,7 @@ RegistrationPage.propTypes = {
email: PropTypes.array,
username: PropTypes.array,
}),
submitState: PropTypes.string,
thirdPartyAuthContext: PropTypes.shape({
currentProvider: PropTypes.string,
platformName: PropTypes.string,
@@ -353,8 +358,9 @@ const mapStateToProps = state => {
const registrationResult = registrationRequestSelector(state);
const thirdPartyAuthContext = thirdPartyAuthContextSelector(state);
return {
registrationResult,
registrationError: state.logistration.registrationError,
submitState: state.logistration.submitState,
registrationResult,
thirdPartyAuthContext,
};
};

View File

@@ -4,11 +4,13 @@ import {
THIRD_PARTY_AUTH_CONTEXT,
} from './actions';
import { DEFAULT_STATE, PENDING_STATE } from '../../data/constants';
export const defaultState = {
registrationResult: {},
loginError: null,
loginResult: {},
registrationError: null,
loginError: null,
registrationResult: {},
};
const reducer = (state = defaultState, action) => {
@@ -16,21 +18,23 @@ const reducer = (state = defaultState, action) => {
case REGISTER_NEW_USER.BEGIN:
return {
...state,
submitState: PENDING_STATE,
};
case REGISTER_NEW_USER.SUCCESS:
return {
...state,
registrationResult: action.payload,
};
case REGISTER_NEW_USER.FAILURE:
return {
...state,
registrationError: action.payload.error,
submitState: DEFAULT_STATE,
};
case LOGIN_REQUEST.BEGIN:
return {
...state,
submitState: PENDING_STATE,
};
case LOGIN_REQUEST.SUCCESS:
return {
@@ -41,6 +45,7 @@ const reducer = (state = defaultState, action) => {
return {
...state,
loginError: action.payload.loginError,
submitState: DEFAULT_STATE,
};
case THIRD_PARTY_AUTH_CONTEXT.BEGIN:
return {

View File

@@ -2,6 +2,16 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'logistration.sign.in.button': {
id: 'logistration.sign.in.button',
defaultMessage: 'Sign in',
description: 'Button label that appears on login page',
},
'logistration.create.account.button': {
id: 'ogistration.create.account.button',
defaultMessage: 'Create Account',
description: 'Button label that appears on register page',
},
'logistration.need.help.signing.in.collapsible.menu': {
id: 'logistration.need.help.signing.in.collapsible.menu',
defaultMessage: 'Need help signing in?',

View File

@@ -8,6 +8,7 @@ import { getConfig } from '@edx/frontend-platform';
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
import LoginPage from '../LoginPage';
import { RenderInstitutionButton } from '../InstitutionLogistration';
import { PENDING_STATE } from '../../data/constants';
const IntlLoginPage = injectIntl(LoginPage);
const mockStore = configureStore();
@@ -64,6 +65,20 @@ describe('LoginPage', () => {
expect(tree).toMatchSnapshot();
});
it('should match pending button state snapshot', () => {
store = mockStore({
...initialState,
logistration: {
...initialState.logistration,
submitState: PENDING_STATE,
},
});
const tree = renderer.create(reduxWrapper(<IntlLoginPage {...props} />))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('should match forget password alert message snapshot', () => {
props = {
...props,
@@ -79,6 +94,7 @@ describe('LoginPage', () => {
logistration: {
...initialState.logistration,
thirdPartyAuthContext: {
...initialState.logistration.thirdPartyAuthContext,
providers: [appleProvider],
},
},
@@ -184,6 +200,7 @@ describe('LoginPage', () => {
logistration: {
...initialState.logistration,
thirdPartyAuthContext: {
...initialState.logistration.thirdPartyAuthContext,
providers: [{
...appleProvider,
loginUrl,

View File

@@ -8,6 +8,7 @@ import { IntlProvider, injectIntl, configure } from '@edx/frontend-platform/i18n
import RegistrationPage from '../RegistrationPage';
import { RenderInstitutionButton } from '../InstitutionLogistration';
import { PENDING_STATE } from '../../data/constants';
const IntlRegistrationPage = injectIntl(RegistrationPage);
const mockStore = configureStore();
@@ -78,6 +79,19 @@ describe('./RegistrationPage.js', () => {
expect(tree.toJSON()).toMatchSnapshot();
});
it('should match pending button state snapshot', () => {
store = mockStore({
...initialState,
logistration: {
...initialState.logistration,
submitState: PENDING_STATE,
},
});
const tree = renderer.create(reduxWrapper(<IntlRegistrationPage {...props} />));
expect(tree.toJSON()).toMatchSnapshot();
});
it('should match TPA provider snapshot', () => {
store = mockStore({
...initialState,

View File

@@ -25,18 +25,11 @@ exports[`LoginPage should match TPA provider snapshot 1`] = `
</a>
</p>
</div>
<h3
className="text-left mt-3"
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h3>
<div
className="section-heading-line mb-4"
>
<h4>
or sign in with
</h4>
</div>
</h2>
<form
className="m-0"
>
@@ -159,12 +152,18 @@ exports[`LoginPage should match TPA provider snapshot 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Sign in
<span
className="d-flex align-items-center justify-content-center"
>
Sign in
</span>
</button>
</form>
<div
@@ -230,18 +229,11 @@ exports[`LoginPage should match default section snapshot 1`] = `
</a>
</p>
</div>
<h3
className="text-left mt-3"
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h3>
<div
className="section-heading-line mb-4"
>
<h4>
or sign in with
</h4>
</div>
</h2>
<form
className="m-0"
>
@@ -364,12 +356,18 @@ exports[`LoginPage should match default section snapshot 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Sign in
<span
className="d-flex align-items-center justify-content-center"
>
Sign in
</span>
</button>
</form>
</div>
@@ -401,18 +399,11 @@ exports[`LoginPage should match forget password alert message snapshot 1`] = `
</a>
</p>
</div>
<h3
className="text-left mt-3"
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h3>
<div
className="section-heading-line mb-4"
>
<h4>
or sign in with
</h4>
</div>
</h2>
<form
className="m-0"
>
@@ -535,12 +526,197 @@ exports[`LoginPage should match forget password alert message snapshot 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Sign in
<span
className="d-flex align-items-center justify-content-center"
>
Sign in
</span>
</button>
</form>
</div>
</div>
`;
exports[`LoginPage should match pending button state snapshot 1`] = `
<div
className="d-flex justify-content-center login-container"
>
<div
className="d-flex flex-column"
style={
Object {
"width": "400px",
}
}
>
<div
className="d-flex flex-row"
>
<p>
First time here?
<a
className="ml-1"
href="/register"
>
Create an Account.
</a>
</p>
</div>
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h2>
<form
className="m-0"
>
<div
className="form-group"
>
<div
className="d-flex flex-column align-items-start"
>
<div
className="form-group"
>
<label
className="h6 mr-1"
htmlFor="loginEmail"
>
Email
</label>
<input
aria-describedby=""
className="form-control"
id="loginEmail"
name="email"
onChange={[Function]}
placeholder="username@domain.com"
style={
Object {
"width": "400px",
}
}
type="email"
value=""
/>
<strong
className="invalid-feedback"
id="email-invalid-feedback"
>
The email address you've provided isn't formatted correctly.
</strong>
</div>
</div>
<p
className="mb-4"
>
The email address you used to register with edX.
</p>
<div
className="d-flex flex-column align-items-start"
>
<div
className="form-group mb-0"
>
<label
className="h6 mr-1"
htmlFor="loginPassword"
>
Password
</label>
<input
aria-describedby=""
className="form-control"
id="loginPassword"
name="password"
onChange={[Function]}
style={
Object {
"width": "400px",
}
}
type="password"
value=""
/>
<strong
className="invalid-feedback"
id="password-invalid-feedback"
>
Please enter your password.
</strong>
</div>
</div>
<button
className="mt-1 field-link"
onClick={[Function]}
type="button"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-caret-right fa-w-6 mr-1"
data-icon="caret-right"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 192 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
fill="currentColor"
style={Object {}}
/>
</svg>
Need help signing in?
</button>
<div
className="pgn-transition-replace-group position-relative"
style={
Object {
"height": null,
}
}
>
<div
style={
Object {
"padding": ".1px 0",
}
}
/>
</div>
</div>
<button
aria-disabled={true}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-pending btn-primary submit disabled btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
>
<span
className="d-flex align-items-center justify-content-center"
>
<span
className="pgn__stateful-btn-icon"
>
<span
aria-hidden={true}
className="icon fa fa-spinner fa-spin"
id="Icon1"
/>
</span>
Sign in
</span>
</button>
</form>
</div>
@@ -595,18 +771,11 @@ exports[`LoginPage should show error message on 400 1`] = `
</a>
</p>
</div>
<h3
className="text-left mt-3"
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h3>
<div
className="section-heading-line mb-4"
>
<h4>
or sign in with
</h4>
</div>
</h2>
<form
className="m-0"
>
@@ -729,12 +898,18 @@ exports[`LoginPage should show error message on 400 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Sign in
<span
className="d-flex align-items-center justify-content-center"
>
Sign in
</span>
</button>
</form>
</div>
@@ -797,18 +972,11 @@ exports[`LoginPage should show error message on 400 on receiving link 1`] = `
</a>
</p>
</div>
<h3
className="text-left mt-3"
<h2
className="font-color text-left mt-2 mb-3"
>
Sign In
</h3>
<div
className="section-heading-line mb-4"
>
<h4>
or sign in with
</h4>
</div>
</h2>
<form
className="m-0"
>
@@ -931,12 +1099,18 @@ exports[`LoginPage should show error message on 400 on receiving link 1`] = `
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Sign in
<span
className="d-flex align-items-center justify-content-center"
>
Sign in
</span>
</button>
</form>
</div>

View File

@@ -1464,12 +1464,18 @@ exports[`./RegistrationPage.js should match TPA provider snapshot 1`] = `
.
</span>
<button
className="btn-primary mt-4 submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit mt-4 btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Create Account
<span
className="d-flex align-items-center justify-content-center"
>
Create Account
</span>
</button>
</form>
</div>
@@ -2899,12 +2905,1468 @@ exports[`./RegistrationPage.js should match default section snapshot 1`] = `
.
</span>
<button
className="btn-primary mt-4 submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit mt-4 btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Create Account
<span
className="d-flex align-items-center justify-content-center"
>
Create Account
</span>
</button>
</form>
</div>
`;
exports[`./RegistrationPage.js should match pending button state snapshot 1`] = `
<div
className="register-container mx-auto"
>
<div
className="text-left"
>
<span>
Already have an edX account?
</span>
<a
href="/login"
>
Sign in.
</a>
</div>
<form
className="mb-4 mx-auto form-group"
>
<div
className="form-group"
>
<label
className="h6 pt-3"
htmlFor="registrationEmail"
>
Email (required)
</label>
<input
aria-describedby=""
className="form-control"
id="registrationEmail"
name="email"
onChange={[Function]}
placeholder="username@domain.com"
required={true}
type="email"
value=""
/>
<strong
className="invalid-feedback"
id="email-invalid-feedback"
>
Enter a valid email address that contains at least 3 characters.
</strong>
</div>
<div
className="form-group"
>
<label
className="h6 pt-3"
htmlFor="registrationName"
>
Full Name (required)
</label>
<input
aria-describedby=""
className="form-control"
id="registrationName"
name="fullname"
onChange={[Function]}
placeholder="Name"
required={true}
type="text"
value=""
/>
<strong
className="invalid-feedback"
id="fullname-invalid-feedback"
>
Enter your full name.
</strong>
</div>
<div
className="form-group"
>
<label
className="h6 pt-3"
htmlFor="registrationUsername"
>
Public Username (required)
</label>
<input
aria-describedby=""
className="form-control"
id="registrationUsername"
name="username"
onChange={[Function]}
placeholder="Username"
required={true}
type="text"
value=""
/>
<strong
className="invalid-feedback"
id="username-invalid-feedback"
>
Username must be between 2 and 30 characters long.
</strong>
</div>
<div
className="form-group"
>
<label
className="h6 pt-3"
htmlFor="registrationPassword"
>
Password (required)
</label>
<input
aria-describedby=""
className="form-control"
id="registrationPassword"
name="password"
onChange={[Function]}
placeholder="Password"
required={true}
type="password"
value=""
/>
<strong
className="invalid-feedback"
id="password-invalid-feedback"
>
This password is too short. It must contain at least 8 characters. This password must contain at least 1 number.
</strong>
</div>
<div
className="form-group"
>
<label
className="h6 pt-3"
htmlFor="registrationCountry"
>
Country (required)
</label>
<select
aria-describedby=""
className="form-control"
name="country"
onChange={[Function]}
placeholder="Country or Region of Residence"
required={true}
value=""
>
<option
value=""
>
Country or Region of Residence (required)
</option>
<option
value="AF"
>
Afghanistan
</option>
<option
value="AL"
>
Albania
</option>
<option
value="DZ"
>
Algeria
</option>
<option
value="AS"
>
American Samoa
</option>
<option
value="AD"
>
Andorra
</option>
<option
value="AO"
>
Angola
</option>
<option
value="AI"
>
Anguilla
</option>
<option
value="AQ"
>
Antarctica
</option>
<option
value="AG"
>
Antigua and Barbuda
</option>
<option
value="AR"
>
Argentina
</option>
<option
value="AM"
>
Armenia
</option>
<option
value="AW"
>
Aruba
</option>
<option
value="AU"
>
Australia
</option>
<option
value="AT"
>
Austria
</option>
<option
value="AZ"
>
Azerbaijan
</option>
<option
value="BS"
>
Bahamas
</option>
<option
value="BH"
>
Bahrain
</option>
<option
value="BD"
>
Bangladesh
</option>
<option
value="BB"
>
Barbados
</option>
<option
value="BY"
>
Belarus
</option>
<option
value="BE"
>
Belgium
</option>
<option
value="BZ"
>
Belize
</option>
<option
value="BJ"
>
Benin
</option>
<option
value="BM"
>
Bermuda
</option>
<option
value="BT"
>
Bhutan
</option>
<option
value="BO"
>
Bolivia
</option>
<option
value="BA"
>
Bosnia and Herzegovina
</option>
<option
value="BW"
>
Botswana
</option>
<option
value="BV"
>
Bouvet Island
</option>
<option
value="BR"
>
Brazil
</option>
<option
value="IO"
>
British Indian Ocean Territory
</option>
<option
value="BN"
>
Brunei Darussalam
</option>
<option
value="BG"
>
Bulgaria
</option>
<option
value="BF"
>
Burkina Faso
</option>
<option
value="BI"
>
Burundi
</option>
<option
value="KH"
>
Cambodia
</option>
<option
value="CM"
>
Cameroon
</option>
<option
value="CA"
>
Canada
</option>
<option
value="CV"
>
Cape Verde
</option>
<option
value="KY"
>
Cayman Islands
</option>
<option
value="CF"
>
Central African Republic
</option>
<option
value="TD"
>
Chad
</option>
<option
value="CL"
>
Chile
</option>
<option
value="CN"
>
China
</option>
<option
value="CX"
>
Christmas Island
</option>
<option
value="CC"
>
Cocos (Keeling) Islands
</option>
<option
value="CO"
>
Colombia
</option>
<option
value="KM"
>
Comoros
</option>
<option
value="CG"
>
Congo
</option>
<option
value="CD"
>
Congo, the Democratic Republic of the
</option>
<option
value="CK"
>
Cook Islands
</option>
<option
value="CR"
>
Costa Rica
</option>
<option
value="CI"
>
Cote D'Ivoire
</option>
<option
value="HR"
>
Croatia
</option>
<option
value="CU"
>
Cuba
</option>
<option
value="CY"
>
Cyprus
</option>
<option
value="CZ"
>
Czech Republic
</option>
<option
value="DK"
>
Denmark
</option>
<option
value="DJ"
>
Djibouti
</option>
<option
value="DM"
>
Dominica
</option>
<option
value="DO"
>
Dominican Republic
</option>
<option
value="EC"
>
Ecuador
</option>
<option
value="EG"
>
Egypt
</option>
<option
value="SV"
>
El Salvador
</option>
<option
value="GQ"
>
Equatorial Guinea
</option>
<option
value="ER"
>
Eritrea
</option>
<option
value="EE"
>
Estonia
</option>
<option
value="ET"
>
Ethiopia
</option>
<option
value="FK"
>
Falkland Islands (Malvinas)
</option>
<option
value="FO"
>
Faroe Islands
</option>
<option
value="FJ"
>
Fiji
</option>
<option
value="FI"
>
Finland
</option>
<option
value="FR"
>
France
</option>
<option
value="GF"
>
French Guiana
</option>
<option
value="PF"
>
French Polynesia
</option>
<option
value="TF"
>
French Southern Territories
</option>
<option
value="GA"
>
Gabon
</option>
<option
value="GM"
>
Gambia
</option>
<option
value="GE"
>
Georgia
</option>
<option
value="DE"
>
Germany
</option>
<option
value="GH"
>
Ghana
</option>
<option
value="GI"
>
Gibraltar
</option>
<option
value="GR"
>
Greece
</option>
<option
value="GL"
>
Greenland
</option>
<option
value="GD"
>
Grenada
</option>
<option
value="GP"
>
Guadeloupe
</option>
<option
value="GU"
>
Guam
</option>
<option
value="GT"
>
Guatemala
</option>
<option
value="GN"
>
Guinea
</option>
<option
value="GW"
>
Guinea-Bissau
</option>
<option
value="GY"
>
Guyana
</option>
<option
value="HT"
>
Haiti
</option>
<option
value="HM"
>
Heard Island and Mcdonald Islands
</option>
<option
value="VA"
>
Holy See (Vatican City State)
</option>
<option
value="HN"
>
Honduras
</option>
<option
value="HK"
>
Hong Kong
</option>
<option
value="HU"
>
Hungary
</option>
<option
value="IS"
>
Iceland
</option>
<option
value="IN"
>
India
</option>
<option
value="ID"
>
Indonesia
</option>
<option
value="IR"
>
Iran, Islamic Republic of
</option>
<option
value="IQ"
>
Iraq
</option>
<option
value="IE"
>
Ireland
</option>
<option
value="IL"
>
Israel
</option>
<option
value="IT"
>
Italy
</option>
<option
value="JM"
>
Jamaica
</option>
<option
value="JP"
>
Japan
</option>
<option
value="JO"
>
Jordan
</option>
<option
value="KZ"
>
Kazakhstan
</option>
<option
value="KE"
>
Kenya
</option>
<option
value="KI"
>
Kiribati
</option>
<option
value="KP"
>
North Korea
</option>
<option
value="KR"
>
South Korea
</option>
<option
value="KW"
>
Kuwait
</option>
<option
value="KG"
>
Kyrgyzstan
</option>
<option
value="LA"
>
Lao People's Democratic Republic
</option>
<option
value="LV"
>
Latvia
</option>
<option
value="LB"
>
Lebanon
</option>
<option
value="LS"
>
Lesotho
</option>
<option
value="LR"
>
Liberia
</option>
<option
value="LY"
>
Libya
</option>
<option
value="LI"
>
Liechtenstein
</option>
<option
value="LT"
>
Lithuania
</option>
<option
value="LU"
>
Luxembourg
</option>
<option
value="MO"
>
Macao
</option>
<option
value="MG"
>
Madagascar
</option>
<option
value="MW"
>
Malawi
</option>
<option
value="MY"
>
Malaysia
</option>
<option
value="MV"
>
Maldives
</option>
<option
value="ML"
>
Mali
</option>
<option
value="MT"
>
Malta
</option>
<option
value="MH"
>
Marshall Islands
</option>
<option
value="MQ"
>
Martinique
</option>
<option
value="MR"
>
Mauritania
</option>
<option
value="MU"
>
Mauritius
</option>
<option
value="YT"
>
Mayotte
</option>
<option
value="MX"
>
Mexico
</option>
<option
value="FM"
>
Micronesia, Federated States of
</option>
<option
value="MD"
>
Moldova, Republic of
</option>
<option
value="MC"
>
Monaco
</option>
<option
value="MN"
>
Mongolia
</option>
<option
value="MS"
>
Montserrat
</option>
<option
value="MA"
>
Morocco
</option>
<option
value="MZ"
>
Mozambique
</option>
<option
value="MM"
>
Myanmar
</option>
<option
value="NA"
>
Namibia
</option>
<option
value="NR"
>
Nauru
</option>
<option
value="NP"
>
Nepal
</option>
<option
value="NL"
>
Netherlands
</option>
<option
value="NC"
>
New Caledonia
</option>
<option
value="NZ"
>
New Zealand
</option>
<option
value="NI"
>
Nicaragua
</option>
<option
value="NE"
>
Niger
</option>
<option
value="NG"
>
Nigeria
</option>
<option
value="NU"
>
Niue
</option>
<option
value="NF"
>
Norfolk Island
</option>
<option
value="MK"
>
North Macedonia, Republic of
</option>
<option
value="MP"
>
Northern Mariana Islands
</option>
<option
value="NO"
>
Norway
</option>
<option
value="OM"
>
Oman
</option>
<option
value="PK"
>
Pakistan
</option>
<option
value="PW"
>
Palau
</option>
<option
value="PS"
>
Palestinian Territory, Occupied
</option>
<option
value="PA"
>
Panama
</option>
<option
value="PG"
>
Papua New Guinea
</option>
<option
value="PY"
>
Paraguay
</option>
<option
value="PE"
>
Peru
</option>
<option
value="PH"
>
Philippines
</option>
<option
value="PN"
>
Pitcairn
</option>
<option
value="PL"
>
Poland
</option>
<option
value="PT"
>
Portugal
</option>
<option
value="PR"
>
Puerto Rico
</option>
<option
value="QA"
>
Qatar
</option>
<option
value="RE"
>
Reunion
</option>
<option
value="RO"
>
Romania
</option>
<option
value="RU"
>
Russian Federation
</option>
<option
value="RW"
>
Rwanda
</option>
<option
value="SH"
>
Saint Helena
</option>
<option
value="KN"
>
Saint Kitts and Nevis
</option>
<option
value="LC"
>
Saint Lucia
</option>
<option
value="PM"
>
Saint Pierre and Miquelon
</option>
<option
value="VC"
>
Saint Vincent and the Grenadines
</option>
<option
value="WS"
>
Samoa
</option>
<option
value="SM"
>
San Marino
</option>
<option
value="ST"
>
Sao Tome and Principe
</option>
<option
value="SA"
>
Saudi Arabia
</option>
<option
value="SN"
>
Senegal
</option>
<option
value="SC"
>
Seychelles
</option>
<option
value="SL"
>
Sierra Leone
</option>
<option
value="SG"
>
Singapore
</option>
<option
value="SK"
>
Slovakia
</option>
<option
value="SI"
>
Slovenia
</option>
<option
value="SB"
>
Solomon Islands
</option>
<option
value="SO"
>
Somalia
</option>
<option
value="ZA"
>
South Africa
</option>
<option
value="GS"
>
South Georgia and the South Sandwich Islands
</option>
<option
value="ES"
>
Spain
</option>
<option
value="LK"
>
Sri Lanka
</option>
<option
value="SD"
>
Sudan
</option>
<option
value="SR"
>
Suriname
</option>
<option
value="SJ"
>
Svalbard and Jan Mayen
</option>
<option
value="SZ"
>
Swaziland
</option>
<option
value="SE"
>
Sweden
</option>
<option
value="CH"
>
Switzerland
</option>
<option
value="SY"
>
Syrian Arab Republic
</option>
<option
value="TW"
>
Taiwan
</option>
<option
value="TJ"
>
Tajikistan
</option>
<option
value="TZ"
>
Tanzania, United Republic of
</option>
<option
value="TH"
>
Thailand
</option>
<option
value="TL"
>
Timor-Leste
</option>
<option
value="TG"
>
Togo
</option>
<option
value="TK"
>
Tokelau
</option>
<option
value="TO"
>
Tonga
</option>
<option
value="TT"
>
Trinidad and Tobago
</option>
<option
value="TN"
>
Tunisia
</option>
<option
value="TR"
>
Turkey
</option>
<option
value="TM"
>
Turkmenistan
</option>
<option
value="TC"
>
Turks and Caicos Islands
</option>
<option
value="TV"
>
Tuvalu
</option>
<option
value="UG"
>
Uganda
</option>
<option
value="UA"
>
Ukraine
</option>
<option
value="AE"
>
United Arab Emirates
</option>
<option
value="GB"
>
United Kingdom
</option>
<option
value="US"
>
United States of America
</option>
<option
value="UM"
>
United States Minor Outlying Islands
</option>
<option
value="UY"
>
Uruguay
</option>
<option
value="UZ"
>
Uzbekistan
</option>
<option
value="VU"
>
Vanuatu
</option>
<option
value="VE"
>
Venezuela
</option>
<option
value="VN"
>
Viet Nam
</option>
<option
value="VG"
>
Virgin Islands, British
</option>
<option
value="VI"
>
Virgin Islands, U.S.
</option>
<option
value="WF"
>
Wallis and Futuna
</option>
<option
value="EH"
>
Western Sahara
</option>
<option
value="YE"
>
Yemen
</option>
<option
value="ZM"
>
Zambia
</option>
<option
value="ZW"
>
Zimbabwe
</option>
<option
value="AX"
>
Åland Islands
</option>
<option
value="BQ"
>
Bonaire, Sint Eustatius and Saba
</option>
<option
value="CW"
>
Curaçao
</option>
<option
value="GG"
>
Guernsey
</option>
<option
value="IM"
>
Isle of Man
</option>
<option
value="JE"
>
Jersey
</option>
<option
value="ME"
>
Montenegro
</option>
<option
value="BL"
>
Saint Barthélemy
</option>
<option
value="MF"
>
Saint Martin (French part)
</option>
<option
value="RS"
>
Serbia
</option>
<option
value="SX"
>
Sint Maarten (Dutch part)
</option>
<option
value="SS"
>
South Sudan
</option>
<option
value="XK"
>
Kosovo
</option>
</select>
<strong
className="invalid-feedback"
id="country-invalid-feedback"
>
Select your country or region of residence.
</strong>
</div>
<span>
By creating an account, you agree to the
<a
href="https://www.edx.org/edx-terms-service"
>
Terms of Service and Honor Code
</a>
and you acknowledge that edX and each Member process your personal data in accordance with the
<a
href="https://www.edx.org/edx-privacy-policy"
>
Privacy Policy
</a>
.
</span>
<button
aria-disabled={true}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-pending btn-primary submit mt-4 disabled btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
>
<span
className="d-flex align-items-center justify-content-center"
>
<span
className="pgn__stateful-btn-icon"
>
<span
aria-hidden={true}
className="icon fa fa-spinner fa-spin"
id="Icon1"
/>
</span>
Create Account
</span>
</button>
</form>
</div>
@@ -4372,12 +5834,18 @@ exports[`./RegistrationPage.js should show error message on 409 1`] = `
.
</span>
<button
className="btn-primary mt-4 submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-default btn-primary submit mt-4 btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Create Account
<span
className="d-flex align-items-center justify-content-center"
>
Create Account
</span>
</button>
</form>
</div>

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Button, Input, ValidationFormGroup } from '@edx/paragon';
import { Input, StatefulButton, ValidationFormGroup } from '@edx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { getQueryParameters } from '@edx/frontend-platform';
@@ -123,12 +123,15 @@ const ResetPasswordPage = (props) => {
</ValidationFormGroup>
</div>
</div>
<Button
<StatefulButton
type="submit"
className="btn-primary submit"
state={props.status}
labels={{
default: intl.formatMessage(messages['logistration.reset.password.page.submit.button']),
}}
onClick={e => handleSubmit(e)}
>
{intl.formatMessage(messages['logistration.reset.password.page.submit.button'])}
</Button>
/>
</form>
</div>
</div>

View File

@@ -53,6 +53,21 @@ describe('ResetPasswordPage', () => {
expect(tree).toMatchSnapshot();
});
it('show spinner component during token validation', () => {
props = {
...props,
token_status: 'pending',
match: {
params: {
token: 'test-token',
},
},
};
const tree = renderer.create(reduxWrapper(<IntlResetPasswordPage {...props} />))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('should match invalid token message section snapshot', () => {
props = {
...props,
@@ -63,6 +78,17 @@ describe('ResetPasswordPage', () => {
expect(tree).toMatchSnapshot();
});
it('should match pending reset message section snapshot', () => {
props = {
...props,
token_status: 'valid',
status: 'pending',
};
const tree = renderer.create(reduxWrapper(<IntlResetPasswordPage {...props} />))
.toJSON();
expect(tree).toMatchSnapshot();
});
it('should match successful reset message section snapshot', () => {
props = {
...props,
@@ -139,19 +165,4 @@ describe('ResetPasswordPage', () => {
expect(store.dispatch).toHaveBeenCalledWith(resetPassword(formPayload, props.token, {}));
resetPage.unmount();
});
it('show spinner component during token validation', () => {
props = {
...props,
token_status: 'pending',
match: {
params: {
token: 'test-token',
},
},
};
const tree = renderer.create(reduxWrapper(<IntlResetPasswordPage {...props} />))
.toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -58,6 +58,122 @@ exports[`ResetPasswordPage should match invalid token message section snapshot 1
</div>
`;
exports[`ResetPasswordPage should match pending reset message section snapshot 1`] = `
<div
className="d-flex justify-content-center reset-password-container"
>
<div
className="d-flex flex-column"
style={
Object {
"width": "450px",
}
}
>
<form
className="m-4"
>
<div
className="form-group"
>
<h3
className="text-center mt-3"
>
Reset Your Password
</h3>
<p
className="mb-4"
>
Enter and confirm your new password.
</p>
<div
className="d-flex flex-column align-items-start"
>
<div
className="form-group"
>
<label
className="h6 mr-1"
htmlFor="reset-password-input"
>
New Password
</label>
<input
aria-describedby=""
className="form-control"
id="reset-password-input"
name="new-password1"
onBlur={[Function]}
placeholder=""
style={
Object {
"width": "400px",
}
}
type="password"
/>
</div>
<div
className="form-group"
>
<label
className="h6 mr-1"
htmlFor="confirm-password-input"
>
Confirm Password
</label>
<input
aria-describedby=""
className="form-control"
id="confirm-password-input"
name="new-password2"
onChange={[Function]}
placeholder=""
style={
Object {
"width": "400px",
}
}
type="password"
value=""
/>
<strong
className="invalid-feedback"
id="confirm-password-input-invalid-feedback"
>
Passwords do not match.
</strong>
</div>
</div>
</div>
<button
aria-disabled={true}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-pending btn-primary submit disabled btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
>
<span
className="d-flex align-items-center justify-content-center"
>
<span
className="pgn__stateful-btn-icon"
>
<span
aria-hidden={true}
className="icon fa fa-spinner fa-spin"
id="Icon1"
/>
</span>
Reset my password
</span>
</button>
</form>
</div>
</div>
`;
exports[`ResetPasswordPage should match reset password default section snapshot 1`] = `
<div
className="d-flex justify-content-center reset-password-container"
@@ -147,12 +263,18 @@ exports[`ResetPasswordPage should match reset password default section snapshot
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-null btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Reset my password
<span
className="d-flex align-items-center justify-content-center"
>
Reset my password
</span>
</button>
</form>
</div>
@@ -345,12 +467,18 @@ Array [
</div>
</div>
<button
className="btn-primary submit btn btn-primary"
aria-disabled={false}
aria-live="assertive"
className="pgn__stateful-btn pgn__stateful-btn-state-failure btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="button"
type="submit"
>
Reset my password
<span
className="d-flex align-items-center justify-content-center"
>
Reset my password
</span>
</button>
</form>
</div>