Add test behavior VisitPageAndWaitUrlIs.

pull/330/head
Clement Michaud 2019-02-12 23:41:19 +01:00
parent c579355c5b
commit 595ee97182
13 changed files with 82 additions and 40 deletions

View File

@ -1,12 +1,12 @@
import VisitPage from "./VisitPage";
import FillLoginPageAndClick from "./FillLoginPageAndClick";
import ValidateTotp from "./ValidateTotp";
import VerifyUrlIs from "./assertions/VerifyUrlIs";
import { WebDriver } from "selenium-webdriver";
import VisitPageAndWaitUrlIs from "./behaviors/VisitPageAndWaitUrlIs";
// Validate the two factors!
export default async function(driver: WebDriver, user: string, secret: string, url: string) {
await VisitPage(driver, `https://login.example.com:8080/?rd=${url}`);
await VisitPageAndWaitUrlIs(driver, `https://login.example.com:8080/?rd=${url}`);
await FillLoginPageAndClick(driver, user, 'password');
await ValidateTotp(driver, secret);
await VerifyUrlIs(driver, url);

View File

@ -1,8 +1,8 @@
import VisitPage from "./VisitPage";
import FillLoginPageAndClick from './FillLoginPageAndClick';
import { WebDriver } from "selenium-webdriver";
import VisitPageAndWaitUrlIs from "./behaviors/VisitPageAndWaitUrlIs";
export default async function(driver: WebDriver, user: string, password: string = "password") {
await VisitPage(driver, "https://login.example.com:8080/");
await VisitPageAndWaitUrlIs(driver, "https://login.example.com:8080/");
await FillLoginPageAndClick(driver, user, password);
}

View File

@ -1,6 +1,5 @@
import SeleniumWebdriver, { WebDriver } from "selenium-webdriver";
export default async function(driver: WebDriver, url: string, timeout: number = 5000) {
await driver.get(url)
await driver.wait(SeleniumWebdriver.until.urlIs(url), timeout);
await driver.get(url);
}

View File

@ -1,9 +1,7 @@
import { WebDriver } from "selenium-webdriver";
import LoginAndRegisterTotp from "../LoginAndRegisterTotp";
import FullLogin from "../FullLogin";
import VisitPage from "../VisitPage";
import FillLoginPageAndClick from "../FillLoginPageAndClick";
import VerifyUrlIs from "../assertions/VerifyUrlIs";
import VisitPageAndWaitUrlIs from "./VisitPageAndWaitUrlIs";
export default async function(
driver: WebDriver,
@ -11,7 +9,7 @@ export default async function(
password: string,
targetUrl: string) {
await VisitPage(driver, `https://login.example.com:8080/?rd=${targetUrl}`);
await VisitPageAndWaitUrlIs(driver, `https://login.example.com:8080/?rd=${targetUrl}`);
await FillLoginPageAndClick(driver, username, password);
await VerifyUrlIs(driver, targetUrl);
};

View File

@ -0,0 +1,8 @@
import { WebDriver } from "selenium-webdriver";
import VerifyUrlIs from "../assertions/VerifyUrlIs";
import VisitPage from "../VisitPage";
export default async function(driver: WebDriver, url: string, timeout: number = 5000) {
await VisitPage(driver, url);
await VerifyUrlIs(driver, url);
}

View File

@ -3,6 +3,7 @@ import MongoConnectionRecovery from "./scenarii/MongoConnectionRecovery";
import EnforceInternalRedirectionsOnly from "./scenarii/EnforceInternalRedirectionsOnly";
import AccessControl from "./scenarii/AccessControl";
import CustomHeadersForwarded from "./scenarii/CustomHeadersForwarded";
import SingleFactorAuthentication from "./scenarii/SingleFactorAuthentication";
AutheliaSuite('Complete configuration', __dirname + '/config.yml', function() {
this.timeout(10000);
@ -12,4 +13,5 @@ AutheliaSuite('Complete configuration', __dirname + '/config.yml', function() {
describe('Mongo broken connection recovery', MongoConnectionRecovery);
describe('Enforce internal redirections only', EnforceInternalRedirectionsOnly);
describe('Single factor authentication', SingleFactorAuthentication);
});

View File

@ -6,17 +6,18 @@ import FillLoginPageAndClick from "../../../helpers/FillLoginPageAndClick";
import ValidateTotp from "../../../helpers/ValidateTotp";
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
import Logout from "../../../helpers/Logout";
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
async function ShouldHaveAccessTo(url: string) {
it('should have access to ' + url, async function() {
await VisitPage(this.driver, url);
await VisitPageAndWaitUrlIs(this.driver, url);
await VerifySecretObserved(this.driver);
})
}
async function ShouldNotHaveAccessTo(url: string) {
it('should not have access to ' + url, async function() {
await this.driver.get(url);
await VisitPage(this.driver, url);
await VerifyUrlIs(this.driver, 'https://login.example.com:8080/');
})
}
@ -34,7 +35,7 @@ export default function() {
before(async function() {
const secret = await LoginAndRegisterTotp(this.driver, "john", true);
await VisitPage(this.driver, 'https://login.example.com:8080/');
await VisitPageAndWaitUrlIs(this.driver, 'https://login.example.com:8080/');
await FillLoginPageAndClick(this.driver, 'john', 'password', false);
await ValidateTotp(this.driver, secret);
})
@ -61,7 +62,7 @@ export default function() {
before(async function() {
const secret = await LoginAndRegisterTotp(this.driver, "bob", true);
await VisitPage(this.driver, 'https://login.example.com:8080/');
await VisitPageAndWaitUrlIs(this.driver, 'https://login.example.com:8080/');
await FillLoginPageAndClick(this.driver, 'bob', 'password', false);
await ValidateTotp(this.driver, secret);
})
@ -88,7 +89,7 @@ export default function() {
before(async function() {
const secret = await LoginAndRegisterTotp(this.driver, "harry", true);
await VisitPage(this.driver, 'https://login.example.com:8080/');
await VisitPageAndWaitUrlIs(this.driver, 'https://login.example.com:8080/');
await FillLoginPageAndClick(this.driver, 'harry', 'password', false);
await ValidateTotp(this.driver, secret);
})

View File

@ -1,11 +1,11 @@
import LoginAndRegisterTotp from "../../../helpers/LoginAndRegisterTotp";
import VisitPage from "../../../helpers/VisitPage";
import FillLoginPageWithUserAndPasswordAndClick from '../../../helpers/FillLoginPageAndClick';
import ValidateTotp from "../../../helpers/ValidateTotp";
import Logout from "../../../helpers/Logout";
import WaitRedirected from "../../../helpers/WaitRedirected";
import IsAlreadyAuthenticatedStage from "../../../helpers/assertions/VerifyIsAlreadyAuthenticatedStage";
import VerifyIsAlreadyAuthenticatedStage from "../../../helpers/assertions/VerifyIsAlreadyAuthenticatedStage";
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
/*
* Authelia should not be vulnerable to open redirection. Otherwise it would aid an
@ -31,19 +31,19 @@ export default function() {
function CannotRedirectTo(url: string) {
it(`should redirect to already authenticated page when requesting ${url}`, async function() {
await VisitPage(this.driver, `https://login.example.com:8080/?rd=${url}`);
await VisitPageAndWaitUrlIs(this.driver, `https://login.example.com:8080/?rd=${url}`);
await FillLoginPageWithUserAndPasswordAndClick(this.driver, 'john', 'password');
await ValidateTotp(this.driver, secret);
await IsAlreadyAuthenticatedStage(this.driver);
await VerifyIsAlreadyAuthenticatedStage(this.driver);
});
}
function CanRedirectTo(url: string) {
it(`should redirect to ${url}`, async function() {
await VisitPage(this.driver, `https://login.example.com:8080/?rd=${url}`);
await VisitPageAndWaitUrlIs(this.driver, `https://login.example.com:8080/?rd=${url}`);
await FillLoginPageWithUserAndPasswordAndClick(this.driver, 'john', 'password');
await ValidateTotp(this.driver, secret);
await WaitRedirected(this.driver, url);
await VerifyUrlIs(this.driver, url);
});
}

View File

@ -0,0 +1,34 @@
import Logout from "../../../helpers/Logout";
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
import LoginOneFactor from "../../../helpers/behaviors/LoginOneFactor";
import VerifySecretObserved from "../../../helpers/assertions/VerifySecretObserved";
import VisitPage from "../../../helpers/VisitPage";
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
export default function() {
beforeEach(async function() {
this.driver = await StartDriver();
});
afterEach(async function() {
await Logout(this.driver);
await StopDriver(this.driver);
});
it("should redirect user after first stage", async function() {
await LoginOneFactor(this.driver, "john", "password", "https://single_factor.example.com:8080/secret.html");
await VerifySecretObserved(this.driver);
});
it("should redirect to portal if not enough authorized", async function() {
await LoginOneFactor(this.driver, "john", "password", "https://single_factor.example.com:8080/secret.html");
await VisitPage(this.driver, "https://admin.example.com:8080/secret.html");
// the url should be the one from the portal.
await VerifyUrlIs(this.driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
// And the user should end up on the second factor page.
await VerifyIsSecondFactorStage(this.driver);
})
}

View File

@ -1,7 +1,7 @@
import FillLoginPageWithUserAndPasswordAndClick from '../../../helpers/FillLoginPageAndClick';
import VisitPage from '../../../helpers/VisitPage';
import SeeNotification from '../../../helpers/SeeNotification';
import {AUTHENTICATION_FAILED} from '../../../../shared/UserMessages';
import VisitPageAndWaitUrlIs from '../../../helpers/behaviors/VisitPageAndWaitUrlIs';
export default function() {
/**
@ -11,7 +11,7 @@ export default function() {
describe('failed login as john in first factor', function() {
beforeEach(async function() {
this.timeout(10000);
await VisitPage(this.driver, "https://login.example.com:8080/")
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/")
await FillLoginPageWithUserAndPasswordAndClick(this.driver, 'john', 'bad_password');
});

View File

@ -1,9 +1,9 @@
import LoginAndRegisterTotp from "../../../helpers/LoginAndRegisterTotp";
import VisitPage from "../../../helpers/VisitPage";
import FillLoginPageWithUserAndPasswordAndClick from "../../../helpers/FillLoginPageAndClick";
import ValidateTotp from "../../../helpers/ValidateTotp";
import WaitRedirected from "../../../helpers/WaitRedirected";
import { WebDriver } from "selenium-webdriver";
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
export default function(this: Mocha.ISuiteCallbackContext) {
this.timeout(20000);
@ -14,11 +14,11 @@ export default function(this: Mocha.ISuiteCallbackContext) {
it("should disconnect user after inactivity period", async function() {
const driver = this.driver as WebDriver;
await VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await VisitPageAndWaitUrlIs(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password', false);
await ValidateTotp(driver, this.secret);
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");
await VisitPage(driver, "https://home.example.com:8080/");
await VisitPageAndWaitUrlIs(driver, "https://home.example.com:8080/");
await driver.sleep(6000);
await driver.get("https://admin.example.com:8080/secret.html");
await WaitRedirected(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
@ -26,11 +26,11 @@ export default function(this: Mocha.ISuiteCallbackContext) {
it('should disconnect user after cookie expiration', async function() {
const driver = this.driver as WebDriver;
await VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await VisitPageAndWaitUrlIs(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password', false);
await ValidateTotp(driver, this.secret);
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");
await VisitPage(driver, "https://home.example.com:8080/");
await VisitPageAndWaitUrlIs(driver, "https://home.example.com:8080/");
await driver.sleep(4000);
await driver.get("https://admin.example.com:8080/secret.html");
@ -46,11 +46,11 @@ export default function(this: Mocha.ISuiteCallbackContext) {
describe('With remember me checkbox checked', function() {
it("should keep user logged in after inactivity period", async function() {
const driver = this.driver as WebDriver;
await VisitPage(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await VisitPageAndWaitUrlIs(driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await FillLoginPageWithUserAndPasswordAndClick(driver, 'john', 'password', true);
await ValidateTotp(driver, this.secret);
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");
await VisitPage(driver, "https://home.example.com:8080/");
await VisitPageAndWaitUrlIs(driver, "https://home.example.com:8080/");
await driver.sleep(6000);
await driver.get("https://admin.example.com:8080/secret.html");
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");

View File

@ -1,6 +1,5 @@
import SeleniumWebDriver from 'selenium-webdriver';
import VisitPage from '../../../helpers/VisitPage';
import ClickOnLink from '../../../helpers/ClickOnLink';
import ClickOn from '../../../helpers/ClickOn';
import WaitRedirected from '../../../helpers/WaitRedirected';
@ -9,10 +8,11 @@ import {GetLinkFromEmail} from "../../../helpers/GetIdentityLink";
import FillLoginPageAndClick from "../../../helpers/FillLoginPageAndClick";
import IsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
import SeeNotification from '../../../helpers/SeeNotification';
import VisitPageAndWaitUrlIs from '../../../helpers/behaviors/VisitPageAndWaitUrlIs';
export default function() {
it("should reset password for john", async function() {
await VisitPage(this.driver, "https://login.example.com:8080/");
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/");
await ClickOnLink(this.driver, "Forgot password\?");
await WaitRedirected(this.driver, "https://login.example.com:8080/forgot-password");
await FillField(this.driver, "username", "john");
@ -21,7 +21,7 @@ export default function() {
await this.driver.sleep(500); // Simulate the time it takes to receive the e-mail.
const link = await GetLinkFromEmail();
await VisitPage(this.driver, link);
await VisitPageAndWaitUrlIs(this.driver, link);
await FillField(this.driver, "password1", "newpass");
await FillField(this.driver, "password2", "newpass");
await ClickOn(this.driver, SeleniumWebDriver.By.id('reset-button'));
@ -33,7 +33,7 @@ export default function() {
});
it("should persuade reset password is initiated for unknown user", async function() {
await VisitPage(this.driver, "https://login.example.com:8080/");
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/");
await ClickOnLink(this.driver, "Forgot password\?");
await WaitRedirected(this.driver, "https://login.example.com:8080/forgot-password");
await FillField(this.driver, "username", "unknown");
@ -44,7 +44,7 @@ export default function() {
});
it("should notify passwords are different in reset form", async function() {
await VisitPage(this.driver, "https://login.example.com:8080/");
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/");
await ClickOnLink(this.driver, "Forgot password\?");
await WaitRedirected(this.driver, "https://login.example.com:8080/forgot-password");
await FillField(this.driver, "username", "john");
@ -53,7 +53,7 @@ export default function() {
await this.driver.sleep(500); // Simulate the time it takes to receive the e-mail.
const link = await GetLinkFromEmail();
await VisitPage(this.driver, link);
await VisitPageAndWaitUrlIs(this.driver, link);
await FillField(this.driver, "password1", "newpass");
await FillField(this.driver, "password2", "badpass");
await ClickOn(this.driver, SeleniumWebDriver.By.id('reset-button'));

View File

@ -1,11 +1,11 @@
import FillLoginPageWithUserAndPasswordAndClick from '../../../helpers/FillLoginPageAndClick';
import WaitRedirected from '../../../helpers/WaitRedirected';
import VisitPage from '../../../helpers/VisitPage';
import ValidateTotp from '../../../helpers/ValidateTotp';
import VerifySecretObserved from "../../../helpers/assertions/VerifySecretObserved";
import LoginAndRegisterTotp from '../../../helpers/LoginAndRegisterTotp';
import SeeNotification from '../../../helpers/SeeNotification';
import { AUTHENTICATION_TOTP_FAILED } from '../../../../shared/UserMessages';
import VisitPageAndWaitUrlIs from '../../../helpers/behaviors/VisitPageAndWaitUrlIs';
export default function() {
/**
@ -18,7 +18,7 @@ export default function() {
const secret = await LoginAndRegisterTotp(this.driver, "john", true);
if (!secret) throw new Error('No secret!');
await VisitPage(this.driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await FillLoginPageWithUserAndPasswordAndClick(this.driver, 'john', 'password');
await ValidateTotp(this.driver, secret);
await WaitRedirected(this.driver, "https://admin.example.com:8080/secret.html");
@ -39,7 +39,7 @@ export default function() {
await LoginAndRegisterTotp(this.driver, "john", true);
const BAD_TOKEN = "125478";
await VisitPage(this.driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await VisitPageAndWaitUrlIs(this.driver, "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html");
await FillLoginPageWithUserAndPasswordAndClick(this.driver, 'john', 'password');
await ValidateTotp(this.driver, BAD_TOKEN);
});