Fix integration tests.
parent
a4b129a676
commit
28cc5e7e1b
|
@ -12,7 +12,6 @@ export interface StateProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DispatchProps {
|
export interface DispatchProps {
|
||||||
onInit: () => void;
|
|
||||||
onOneTimePasswordMethodClicked: () => void;
|
onOneTimePasswordMethodClicked: () => void;
|
||||||
onSecurityKeyMethodClicked: () => void;
|
onSecurityKeyMethodClicked: () => void;
|
||||||
onDuoPushMethodClicked: () => void;
|
onDuoPushMethodClicked: () => void;
|
||||||
|
@ -27,10 +26,6 @@ interface MethodDescription {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UseAnotherMethod extends Component<Props> {
|
class UseAnotherMethod extends Component<Props> {
|
||||||
componentDidMount() {
|
|
||||||
this.props.onInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const methods: MethodDescription[] = [
|
const methods: MethodDescription[] = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,10 @@ import LogoutBehavior from '../../../behaviors/LogoutBehavior';
|
||||||
import { RootState } from '../../../reducers';
|
import { RootState } from '../../../reducers';
|
||||||
import { StateProps, DispatchProps } from '../../../components/SecondFactorForm/SecondFactorForm';
|
import { StateProps, DispatchProps } from '../../../components/SecondFactorForm/SecondFactorForm';
|
||||||
import FetchPrefered2faMethod from '../../../behaviors/FetchPrefered2faMethod';
|
import FetchPrefered2faMethod from '../../../behaviors/FetchPrefered2faMethod';
|
||||||
import { setUseAnotherMethod } from '../../../reducers/Portal/SecondFactor/actions';
|
import { setUseAnotherMethod, setSecurityKeySupported } from '../../../reducers/Portal/SecondFactor/actions';
|
||||||
|
import GetAvailable2faMethods from '../../../behaviors/GetAvailable2faMethods';
|
||||||
|
import u2fApi from 'u2f-api';
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState): StateProps => {
|
const mapStateToProps = (state: RootState): StateProps => {
|
||||||
return {
|
return {
|
||||||
|
@ -16,7 +19,11 @@ const mapStateToProps = (state: RootState): StateProps => {
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
|
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
|
||||||
return {
|
return {
|
||||||
onInit: () => FetchPrefered2faMethod(dispatch),
|
onInit: async () => {
|
||||||
|
dispatch(setSecurityKeySupported(await u2fApi.isSupported()));
|
||||||
|
FetchPrefered2faMethod(dispatch);
|
||||||
|
GetAvailable2faMethods(dispatch);
|
||||||
|
},
|
||||||
onLogoutClicked: () => LogoutBehavior(dispatch),
|
onLogoutClicked: () => LogoutBehavior(dispatch),
|
||||||
onUseAnotherMethodClicked: () => dispatch(setUseAnotherMethod(true)),
|
onUseAnotherMethodClicked: () => dispatch(setUseAnotherMethod(true)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,6 @@ import SetPrefered2faMethod from '../../../behaviors/SetPrefered2faMethod';
|
||||||
import { getPreferedMethodSuccess, setUseAnotherMethod, setSecurityKeySupported } from '../../../reducers/Portal/SecondFactor/actions';
|
import { getPreferedMethodSuccess, setUseAnotherMethod, setSecurityKeySupported } from '../../../reducers/Portal/SecondFactor/actions';
|
||||||
import Method2FA from '../../../types/Method2FA';
|
import Method2FA from '../../../types/Method2FA';
|
||||||
import UseAnotherMethod, {StateProps, DispatchProps} from '../../../components/UseAnotherMethod/UseAnotherMethod';
|
import UseAnotherMethod, {StateProps, DispatchProps} from '../../../components/UseAnotherMethod/UseAnotherMethod';
|
||||||
import GetAvailable2faMethods from '../../../behaviors/GetAvailable2faMethods';
|
|
||||||
import u2fApi from 'u2f-api';
|
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState): StateProps => ({
|
const mapStateToProps = (state: RootState): StateProps => ({
|
||||||
availableMethods: state.secondFactor.getAvailableMethodResponse,
|
availableMethods: state.secondFactor.getAvailableMethodResponse,
|
||||||
|
@ -25,10 +22,6 @@ async function storeMethod(dispatch: Dispatch, method: Method2FA) {
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
|
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => {
|
||||||
return {
|
return {
|
||||||
onInit: async () => {
|
|
||||||
dispatch(setSecurityKeySupported(await u2fApi.isSupported()));
|
|
||||||
await GetAvailable2faMethods(dispatch);
|
|
||||||
},
|
|
||||||
onOneTimePasswordMethodClicked: () => storeMethod(dispatch, 'totp'),
|
onOneTimePasswordMethodClicked: () => storeMethod(dispatch, 'totp'),
|
||||||
onSecurityKeyMethodClicked: () => storeMethod(dispatch, 'u2f'),
|
onSecurityKeyMethodClicked: () => storeMethod(dispatch, 'u2f'),
|
||||||
onDuoPushMethodClicked: () => storeMethod(dispatch, "duo_push"),
|
onDuoPushMethodClicked: () => storeMethod(dispatch, "duo_push"),
|
||||||
|
|
|
@ -8,5 +8,9 @@ import VerifyElementDoesNotExist from "./VerifyElementDoesNotExist";
|
||||||
* @param content The content of the button to select.
|
* @param content The content of the button to select.
|
||||||
*/
|
*/
|
||||||
export default async function(driver: WebDriver, content: string) {
|
export default async function(driver: WebDriver, content: string) {
|
||||||
await VerifyElementDoesNotExist(driver, SeleniumWebDriver.By.xpath("//button[text()='" + content + "']"))
|
try {
|
||||||
|
await VerifyElementDoesNotExist(driver, SeleniumWebDriver.By.xpath("//button[text()='" + content + "']"));
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Button with content "${content}" should not exist.`);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import SeleniumWebDriver, { WebDriver } from "selenium-webdriver";
|
import SeleniumWebDriver, { WebDriver } from "selenium-webdriver";
|
||||||
import VerifyElementExists from "./VerifyElementExists";
|
import VerifyHasAppeared from "./VerifyHasAppeared";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify if a button with given content exists in the DOM.
|
* Verify if a button with given content exists in the DOM.
|
||||||
|
@ -7,5 +7,9 @@ import VerifyElementExists from "./VerifyElementExists";
|
||||||
* @param content The content of the button to find in the DOM.
|
* @param content The content of the button to find in the DOM.
|
||||||
*/
|
*/
|
||||||
export default async function(driver: WebDriver, content: string) {
|
export default async function(driver: WebDriver, content: string) {
|
||||||
await VerifyElementExists(driver, SeleniumWebDriver.By.xpath("//button[text()='" + content + "']"));
|
try {
|
||||||
|
await VerifyHasAppeared(driver, SeleniumWebDriver.By.xpath("//button[text()='" + content + "']"));
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Button with content "${content}" should have appeared.`);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import SeleniumWebDriver, { WebDriver } from "selenium-webdriver";
|
||||||
|
|
||||||
|
export default async function(driver: WebDriver, timeout: number = 5000) {
|
||||||
|
await driver.wait(SeleniumWebDriver.until.elementLocated(
|
||||||
|
SeleniumWebDriver.By.className('duo-push-view')), timeout);
|
||||||
|
}
|
|
@ -3,10 +3,8 @@ import LoginAs from "../../../helpers/LoginAs";
|
||||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||||
import ClickOnLink from "../../../helpers/ClickOnLink";
|
import ClickOnLink from "../../../helpers/ClickOnLink";
|
||||||
import VerifyIsUseAnotherMethodView from "../../../helpers/assertions/VerifyIsUseAnotherMethodView";
|
import VerifyIsUseAnotherMethodView from "../../../helpers/assertions/VerifyIsUseAnotherMethodView";
|
||||||
import VerifyElementDoesNotExist from "../../../helpers/assertions/VerifyElementDoesNotExist";
|
|
||||||
import SeleniumWebDriver from "selenium-webdriver";
|
|
||||||
import VerifyButtonDoesNotExist from "../../../helpers/assertions/VerifyButtonDoesNotExist";
|
import VerifyButtonDoesNotExist from "../../../helpers/assertions/VerifyButtonDoesNotExist";
|
||||||
import VerifyButtonExists from "../../../helpers/assertions/VerifyButtonExists";
|
import VerifyButtonHasAppeared from "../../../helpers/assertions/VerifyButtonHasAppeared";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,8 +24,7 @@ export default function() {
|
||||||
|
|
||||||
await ClickOnLink(this.driver, 'Use another method');
|
await ClickOnLink(this.driver, 'Use another method');
|
||||||
await VerifyIsUseAnotherMethodView(this.driver);
|
await VerifyIsUseAnotherMethodView(this.driver);
|
||||||
await VerifyButtonExists(this.driver, "Security Key (U2F)");
|
await VerifyButtonHasAppeared(this.driver, "One-Time Password");
|
||||||
await VerifyButtonExists(this.driver, "One-Time Password");
|
|
||||||
await VerifyButtonDoesNotExist(this.driver, "Duo Push Notification");
|
await VerifyButtonDoesNotExist(this.driver, "Duo Push Notification");
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -10,7 +10,6 @@ import LogoutRedirectToAlreadyLoggedIn from './scenarii/LogoutRedirectToAlreadyL
|
||||||
import { exec } from '../../helpers/utils/exec';
|
import { exec } from '../../helpers/utils/exec';
|
||||||
import TwoFactorAuthentication from "../../helpers/scenarii/TwoFactorAuthentication";
|
import TwoFactorAuthentication from "../../helpers/scenarii/TwoFactorAuthentication";
|
||||||
import BypassPolicy from "./scenarii/BypassPolicy";
|
import BypassPolicy from "./scenarii/BypassPolicy";
|
||||||
import Prefered2faMethod from "./scenarii/Prefered2faMethod";
|
|
||||||
import NoDuoPushOption from "./scenarii/NoDuoPushOption";
|
import NoDuoPushOption from "./scenarii/NoDuoPushOption";
|
||||||
|
|
||||||
AutheliaSuite(__dirname, function() {
|
AutheliaSuite(__dirname, function() {
|
||||||
|
@ -30,6 +29,5 @@ AutheliaSuite(__dirname, function() {
|
||||||
describe('TOTP Validation', TOTPValidation);
|
describe('TOTP Validation', TOTPValidation);
|
||||||
describe('Required two factor', RequiredTwoFactor);
|
describe('Required two factor', RequiredTwoFactor);
|
||||||
describe('Logout endpoint redirect to already logged in page', LogoutRedirectToAlreadyLoggedIn);
|
describe('Logout endpoint redirect to already logged in page', LogoutRedirectToAlreadyLoggedIn);
|
||||||
describe('Prefered 2FA method', Prefered2faMethod);
|
|
||||||
describe('No Duo Push method available', NoDuoPushOption);
|
describe('No Duo Push method available', NoDuoPushOption);
|
||||||
});
|
});
|
|
@ -6,6 +6,7 @@ import VerifyIsUseAnotherMethodView from "../../../helpers/assertions/VerifyIsUs
|
||||||
import ClickOnButton from "../../../helpers/behaviors/ClickOnButton";
|
import ClickOnButton from "../../../helpers/behaviors/ClickOnButton";
|
||||||
import VerifyIsSecurityKeyView from "../../../helpers/assertions/VerifyIsSecurityKeyView";
|
import VerifyIsSecurityKeyView from "../../../helpers/assertions/VerifyIsSecurityKeyView";
|
||||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||||
|
import VerifyIsDuoPushNotificationView from "../../../helpers/assertions/VerifyIsDuoPushNotificationView";
|
||||||
|
|
||||||
|
|
||||||
// This fixture tests that the latest used method is still used when the user gets back.
|
// This fixture tests that the latest used method is still used when the user gets back.
|
||||||
|
@ -26,10 +27,10 @@ export default function() {
|
||||||
|
|
||||||
await ClickOnLink(this.driver, 'Use another method');
|
await ClickOnLink(this.driver, 'Use another method');
|
||||||
await VerifyIsUseAnotherMethodView(this.driver);
|
await VerifyIsUseAnotherMethodView(this.driver);
|
||||||
await ClickOnButton(this.driver, 'Security Key (U2F)');
|
await ClickOnButton(this.driver, 'Duo Push Notification');
|
||||||
|
|
||||||
// Verify that the user is redirected to the new method
|
// Verify that the user is redirected to the new method
|
||||||
await VerifyIsSecurityKeyView(this.driver);
|
await VerifyIsDuoPushNotificationView(this.driver);
|
||||||
await ClickOnLink(this.driver, "Logout");
|
await ClickOnLink(this.driver, "Logout");
|
||||||
|
|
||||||
// Login with another user to check that he gets TOTP view.
|
// Login with another user to check that he gets TOTP view.
|
||||||
|
@ -39,7 +40,7 @@ export default function() {
|
||||||
|
|
||||||
// Log john again to check that the prefered method has been persisted
|
// Log john again to check that the prefered method has been persisted
|
||||||
await LoginAs(this.driver, "john", "password", "https://secure.example.com:8080/");
|
await LoginAs(this.driver, "john", "password", "https://secure.example.com:8080/");
|
||||||
await VerifyIsSecurityKeyView(this.driver);
|
await VerifyIsDuoPushNotificationView(this.driver);
|
||||||
|
|
||||||
// Restore the prefered method to one-time password.
|
// Restore the prefered method to one-time password.
|
||||||
await ClickOnLink(this.driver, 'Use another method');
|
await ClickOnLink(this.driver, 'Use another method');
|
|
@ -1,6 +1,7 @@
|
||||||
import AutheliaSuite from "../../helpers/context/AutheliaSuite";
|
import AutheliaSuite from "../../helpers/context/AutheliaSuite";
|
||||||
import { exec } from '../../helpers/utils/exec';
|
import { exec } from '../../helpers/utils/exec';
|
||||||
import DuoPushNotification from "./scenarii/DuoPushNotification";
|
import DuoPushNotification from "./scenarii/DuoPushNotification";
|
||||||
|
import Prefered2faMethod from "./scenarii/Prefered2faMethod";
|
||||||
|
|
||||||
// required to query duo-api over https
|
// required to query duo-api over https
|
||||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0 as any;
|
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0 as any;
|
||||||
|
@ -13,4 +14,5 @@ AutheliaSuite(__dirname, function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Duo Push Notication", DuoPushNotification);
|
describe("Duo Push Notication", DuoPushNotification);
|
||||||
|
describe("Prefered 2FA methods", Prefered2faMethod);
|
||||||
});
|
});
|
Loading…
Reference in New Issue