Skip to content

Instantly share code, notes, and snippets.

@GaryJones
Last active May 20, 2019 15:21
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save GaryJones/284eea905cff882cc7cb to your computer and use it in GitHub Desktop.
Save GaryJones/284eea905cff882cc7cb to your computer and use it in GitHub Desktop.
Codeception 301 Redirection Tests
# Codeception Test Suite Configuration
# suite for redirection tests.
# perform tests in browser using the REST module with redirections NOT followed.
class_name: RedirectsTester
modules:
enabled:
- PhpBrowser
- REST
- RedirectsHelper
config:
PhpBrowser:
url: 'http://www.example.com/'
REST:
url: 'http://www.example.com/'
<?php
$I = new RedirectsTester($scenario);
$I->wantTo('check 301 redirects are working');
// First, test /login/ page gets rewritten to https://
$I->seePermanentRedirectToHttpsFor('login/');
$I->seePermanentRedirectToHttpsFor('login/?redirect_to=foo');
// For all other redirects, a Location header is sent, so we stop the redirect
// and just check that header instead.
$I->followRedirects(false);
// External
$I->sendHead('facebook');
$I->seePermanentRedirectTo('https://www.facebook.com/DanielsTrading');
// Internal link
$I->sendHead('don-debartolo/access');
$I->seePermanentRedirectTo('ddebartolo/#account');
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Redirects extends \Codeception\Module
{
/**
* Check that a 301 HTTP Status is returned with the correct Location URL.
*
* @since 1.0.0
*
* @param string $url Relative or absolute URL of redirect destination.
*/
public function seePermanentRedirectTo($url)
{
// Allow relative URLs.
$testDomain = \Codeception\Configuration::suiteSettings('redirects', \Codeception\Configuration::config())['modules']['enabled'][1]['REST']['url'];
$url = (strpos($url, '://') === false ? $testDomain : '') . $url;
$response = $this->getModule('PhpBrowser')->client->getInternalResponse();
$responseCode = $response->getStatus();
$locationHeader = $response->getHeaders()['Location'][0];
$this->assertEquals(301, $responseCode);
$this->assertEquals($url, $locationHeader);
}
/**
* Check that a 301 HTTP Status is returned with the correct Location URL.
*
* @since 1.0.0
*
* @param string $url Relative or absolute URL of redirect destination.
*/
public function seePermanentRedirectToHttpsFor($url)
{
$this->getModule('REST')->sendHead($url);
// Allow relative URLs.
$testDomain = \Codeception\Configuration::suiteSettings('redirects', \Codeception\Configuration::config())['modules']['enabled'][1]['REST']['url'];
$testDomainHttps = str_replace( 'http://', 'https://', $testDomain );
$url = (strpos($url, '://') === false ? $testDomainHttps : '') . $url;
$client = $this->getModule('PhpBrowser')->client;
$responseCode = $client->getInternalResponse()->getStatus();
$responseUri = $client->getHistory()->current()->getUri();
$this->assertEquals(200, $responseCode);
$this->assertEquals($url, $responseUri);
}
/**
* Toggle redirections on and off.
*
* By default, BrowserKit will follow redirections, so to check for 30*
* HTTP status codes and Location headers, they have to be turned off.
*
* @since 1.0.0
*
* @param bool $followRedirects Optional. Whether to follow redirects or not.
* Default is true.
*/
function followRedirects( $followRedirects = true ) {
$this->getModule('PhpBrowser')->client->followRedirects($followRedirects);
}
}
@GaryJones
Copy link
Author

File locations:

  • tests/redirects/RedirectsCept.php
  • tests/_support/RedirectsHelper.php
  • tests/redirects.suite.yml
  • tests/redirects/_bootstrap.php (empty file)

Adjust the redirects.suite.yml URLs to your domain, and the paths in the Cept to whatever your redirections are.

Upon building / running, this will automatically generate a tests/redirects/RedirectsTester.php file.

Run just this Cept with:

php codecept.phar run tests/redirects/RedirectsTester.php

@comm1x
Copy link

comm1x commented Dec 10, 2015

Thank you, but it is not worked for me :(
Line $client->getInternalResponse()->getStatus(); always return null. And I do not found where url is executing, no requests.
I am partial patched it and get below method.

public function seeRedirect($url, $isPermanent = null, $toLocation = null)
{
    /* @var \Codeception\Module\PhpBrowser $phpBrowser */
    $phpBrowser = $this->getModule('PhpBrowser');
    $guzzle = $phpBrowser->client;
    $guzzle->followRedirects(false);
    $phpBrowser->_loadPage('GET', $url);
    $response = $guzzle->getResponse();

    $responseCode = $response->getStatus();
    $locationHeader = $response->getHeader('Location');

    if ($isPermanent === null) {
        $this->assertContains($responseCode, [301, 302]);
    } else {
        $this->assertEquals($responseCode, $isPermanent ? 301 : 302);
    }

    if ($toLocation !== null) {
        $this->assertEquals($locationHeader, $toLocation);
    }
}

It is not support Https, but it is independ of suite name, line in configuration.
Thank you for hint!

@SimonEast
Copy link

SimonEast commented Aug 1, 2016

Thanks to both of your for your code, which definitely helped. I've written two functions verifyRedirect() and verifyNoRedirect() which can be used for this purpose. You simply pop the code inside _support/Helper/Acceptance.php.

And then can test like this...

$I->verifyRedirect('http://www2.ames.net.au/', 'http://www.ames.net.au/', 301);

View code: https://gist.github.com/SimonEast/b550e04300ac56cb5ac8eea704fccdfa

@SimonEast
Copy link

(I also posted a link to this gist on StackOverflow: http://stackoverflow.com/a/38692837/195835)

@polevaultweb
Copy link

If others find this gist from Google, then there is a module that supersedes it: https://github.com/gamajo/codeception-redirects 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment