Skip to content

Instantly share code, notes, and snippets.

@norcross
Last active March 7, 2019 14:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save norcross/4d45f1902bfb2f1f4cf79997a47d9d03 to your computer and use it in GitHub Desktop.
Save norcross/4d45f1902bfb2f1f4cf79997a47d9d03 to your computer and use it in GitHub Desktop.
Run various acceptance tests for WooCommerce
<?php
/**
* WooCommerce Upgrade Test Suite
*
* A set of acceptance tests for a standard WooCommerce store.
*
* https://gist.github.com/norcross/4d45f1902bfb2f1f4cf79997a47d9d03
*/
// It'll error out sometimes without this ¯\_(ツ)_/¯ .
date_default_timezone_set( 'UTC' );
/**
* Load our test suite class.
*/
class WooUpgradeTestSuiteCest {
/**
* Run all of our single page loading tests. This
* function will loop through the data we set in
* the 'getSinglePages' function.
*/
public function SinglePageLoads( AcceptanceTester $I ) {
// Define what we're doing in a readable way.
$I->wantTo( 'Confirm individual site pages load...' );
// Get all of our single pages.
$single_pages = $this->getSinglePages();
// Bail without any single pages to check.
if ( empty( $single_pages ) ) {
return;
}
// Loop and check each one.
foreach ( $single_pages as $single_page ) {
// Make sure we have all the required variables in the array.
if ( empty( $single_page['page'] ) || empty( $single_page['tags'] ) || empty( $single_page['equal'] ) ) {
continue;
}
// Go to the requested page.
$I->amOnPage( $single_page['page'] );
// Loop all the tags we provided and check each one.
foreach ( (array) $single_page['tags'] as $page_tag ) {
$I->see( $page_tag );
}
// Confirm the resulting URL matches what we expect.
$I->seeCurrentUrlEquals( $single_page['equal'] );
}
}
/**
* Confirm that a user can log in and check
* their existing orders. This requires an
* existing user account on the site.
*/
public function LoadExistingOrders( AcceptanceTester $I ) {
// Define what we're doing in a readable way.
$I->wantTo( 'Testing customer login and view existing orders...' );
// Get all of the customer login fields we defined.
$login_fields = $this->getCustomerLoginFields();
// Bail without any login fields to check.
if ( empty( $login_fields ) ) {
return;
}
// First go to the 'my account page'.
$I->amOnPage( '/my-account/' );
// Now loop the login fields to check each one.
foreach ( $login_fields as $single_field ) {
// Make sure we have all the required variables in the array.
if ( empty( $single_field['value'] ) || empty( $single_field['see'] ) || empty( $single_field['type'] ) || empty( $single_field['name'] ) ) {
continue;
}
// First confirm the field itself exists.
$I->seeElement( $single_field['see'], [ 'name' => $single_field['name'] ] );
// Populate the field based on type.
switch ( $single_field['type'] ) {
case 'select' :
case 'radio' :
$I->selectOption( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
case 'checkbox' :
$I->checkOption( $single_field['name'] );
break;
case 'input' :
case 'textarea' :
$I->fillField( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
// End all case breaks.
}
// Nothing remaining with the fields.
}
// Click the login button.
$I->click( 'form.woocommerce-form-login button[type=submit]' );
// Make sure we end up on the my account page and see the title.
$I->see( 'My Account' );
$I->seeInCurrentUrl( 'my-account' );
// See a link for the orders.
$I->seeLink( 'Orders' );
$I->click( 'Orders' );
$I->seeInCurrentUrl( 'orders' );
}
/**
* Check that the WordPress wp-login page can be logged in.
*/
public function LoginViaWP( AcceptanceTester $I ) {
// Define what we're doing in a readable way.
$I->wantTo( 'Testing customer login using the WordPress admin login page...' );
// Get all of the customer login fields we defined with the admin flag.
$login_fields = $this->getCustomerLoginFields( true );
// Bail without any login fields to check.
if ( empty( $login_fields ) ) {
return;
}
// First go to the wp-login page.
$I->amOnPage( '/wp-login.php' );
// Loop my fields to add the value.
foreach ( $login_fields as $single_field ) {
// Make sure we have all the required variables in the array.
if ( empty( $single_field['value'] ) || empty( $single_field['see'] ) || empty( $single_field['type'] ) || empty( $single_field['name'] ) ) {
continue;
}
// First confirm the field itself exists.
$I->seeElement( $single_field['see'], [ 'name' => $single_field['name'] ] );
// Populate the field based on type.
switch ( $single_field['type'] ) {
case 'select' :
case 'radio' :
$I->selectOption( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
case 'checkbox' :
$I->checkOption( $single_field['name'] );
break;
case 'input' :
case 'textarea' :
$I->fillField( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
// End all case breaks.
}
}
// Click the login button.
$I->click( 'input#wp-submit' );
// Assuming it's redirected to the "my account" page.
$I->seeCurrentUrlEquals( '/my-account/' );
}
/**
* Have a visitor begin on the primary shop page and
* attempt add an item, see the cart, checkout, and
* the review the completed order.
*/
public function VisitorProductPurchase( AcceptanceTester $I ) {
// Define what we're doing in a readable way.
$I->wantTo( 'Testing a site visitor purchasing a product...' );
// Get all of the required fields we defined.
$visitor_fields = $this->getVisitorCheckoutFields();
// Bail without any visitor fields to check.
if ( empty( $visitor_fields ) ) {
return;
}
// This is the shop / adding portion.
$I->amOnPage( '/shop/' );
$I->see( 'Album' );
$I->click( 'Album' );
$I->see( 'Add to cart' );
$I->click( 'Add to cart' );
$I->see( 'View cart' );
$I->seeLink( 'View cart' );
$I->click( 'View cart' );
$I->seeCurrentUrlEquals( '/cart/' );
// Check for elements on the cart page.
$I->see( 'Update cart' );
$I->see( 'Subtotal' );
$I->see( 'Total' );
$I->see( 'Proceed to checkout' );
$I->seeLink( 'Proceed to checkout' );
$I->click( 'Proceed to checkout' );
$I->seeCurrentUrlEquals( '/checkout/' );
// Check for elements on the checkout page.
$I->see( 'Billing details' );
$I->see( 'Your order' );
// Loop my fields to add the value.
foreach ( $visitor_fields as $single_field ) {
// Make sure we have all the required variables in the array.
if ( empty( $single_field['value'] ) || empty( $single_field['see'] ) || empty( $single_field['type'] ) || empty( $single_field['name'] ) ) {
continue;
}
// First confirm the field itself exists.
$I->seeElement( $single_field['see'], [ 'name' => $single_field['name'] ] );
// Populate the field based on type.
switch ( $single_field['type'] ) {
case 'select' :
case 'radio' :
$I->selectOption( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
case 'checkbox' :
$I->checkOption( $single_field['name'] );
break;
case 'input' :
case 'textarea' :
$I->fillField( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
// End all case breaks.
}
// Nothing remaining with the fields.
}
// Click the order button.
$I->click( 'button#place_order' );
// Make sure we end up on the recieved page and see the title.
$I->see( 'Order received' );
$I->seeInCurrentUrl( 'order-received' );
}
/**
* Have an existing customer begin on the primary
* shop page and attempt add an item, see the
* cart, checkout, and the review the completed order.
*/
public function CustomerProductPurchase( AcceptanceTester $I ) {
// Define what we're doing in a readable way.
$I->wantTo( 'Testing an existing customer purchasing a product...' );
// Get all of the customer login fields we defined.
$login_fields = $this->getCustomerLoginFields();
// Bail without any login fields to check.
if ( empty( $login_fields ) ) {
return;
}
// Navigate to the 'my account' page.
$I->amOnPage( '/my-account/' );
// Loop my fields to add the value.
foreach ( $login_fields as $single_field ) {
// Bail without a value,type or name to check.
if ( empty( $single_field['value'] ) || empty( $single_field['type'] ) || empty( $single_field['name'] ) ) {
continue;
}
// Check for what we're gonna see.
$field_see = in_array( $single_field['type'], array( 'input', 'checkbox' ) ) ? 'input' : $single_field['type'];
// Now check for the existence.
$I->seeElement( $field_see, [ 'name' => $single_field['name'] ] );
// Populate the field based on type.
switch ( $single_field['type'] ) {
case 'select' :
case 'radio' :
$I->selectOption( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
case 'checkbox' :
$I->checkOption( $single_field['name'] );
break;
case 'input' :
case 'textarea' :
$I->fillField( [ 'name' => $single_field['name'] ], $single_field['value'] );
break;
// End all case breaks.
}
// Nothing remaining with the fields.
}
// Click the login button.
$I->click( 'form.woocommerce-form-login button[type=submit]' );
// Make sure we end up on the my account page and see the title.
$I->see( 'My Account' );
$I->seeInCurrentUrl( 'my-account' );
// This is the shop / adding portion.
$I->amOnPage( '/shop/' );
$I->see( 'Album' );
$I->click( 'Album' );
$I->see( 'Add to cart' );
$I->click( 'Add to cart' );
$I->see( 'View cart' );
$I->seeLink( 'View cart' );
$I->click( 'View cart' );
$I->seeCurrentUrlEquals( '/cart/' );
// Check for elements on the cart page and checkout.
$I->see( 'Update cart' );
$I->see( 'Subtotal' );
$I->see( 'Total' );
$I->see( 'Proceed to checkout' );
$I->seeLink( 'Proceed to checkout' );
$I->click( 'Proceed to checkout' );
$I->seeCurrentUrlEquals( '/checkout/' );
// Click the order button.
$I->click( 'button#place_order' );
// Make sure we end up on the recieved page and see the title.
$I->see( 'Order received' );
$I->seeInCurrentUrl( 'order-received' );
}
/***************************************************************
* The below functions are datasets or other variables *
* used in the Codeception tests. These should be changed to *
* match the settings used in your WooCommerce store. *
***************************************************************/
/**
* Create and return an array of all the
* basic page variables we want to check.
*
* @return array
*/
private function getSinglePages() {
// Set an array of the pages we wanna check.
return array(
array(
'page' => '/',
'tags' => array( 'WooTesting Alternate' ),
'equal' => '/',
),
array(
'page' => '/shop/',
'tags' => array( 'Shop' ),
'equal' => '/shop/',
),
array(
'page' => '/product/album/',
'tags' => array( 'Album', 'Description' ),
'equal' => '/product/album/',
),
array(
'page' => '/2018/',
'tags' => array( 'Year: 2018' ),
'equal' => '/2018/',
),
array(
'page' => '/my-account/',
'tags' => array( 'My Account', 'Login' ),
'equal' => '/my-account/',
),
);
}
/**
* Set up and return the field data used when
* logging in a user. Change these values to
* match the customer account on your site.
*
* @param boolean $admin Whether the login is happening on admin.
*
* @return array
*/
private function getCustomerLoginFields( $admin = false ) {
// Set my two fields, since the checkboxes match.
$name_field = false !== $admin ? 'log' : 'username';
$pass_field = false !== $admin ? 'pwd' : 'password';
// Set an array of the fields we wanna check.
return array(
array(
'name' => $name_field,
'type' => 'input',
'see' => 'input',
'value' => 'testuser',
),
array(
'name' => $pass_field,
'type' => 'input',
'see' => 'input',
'value' => 'testpassword',
),
array(
'name' => 'rememberme',
'type' => 'checkbox',
'see' => 'input',
'value' => 'forever',
),
);
}
/**
* Set up and return the individual fields
* that exist on the checkout page when the
* user is not logged in. You can change these
* values if you want, but they shouldn't match
* any existing users in the database.
*
* @return array
*/
private function getVisitorCheckoutFields() {
// Set an array of the fields we wanna check.
return array(
array(
'name' => 'billing_first_name',
'type' => 'input',
'see' => 'input',
'value' => 'Test',
),
array(
'name' => 'billing_last_name',
'type' => 'input',
'see' => 'input',
'value' => 'User',
),
array(
'name' => 'billing_country',
'type' => 'select',
'see' => 'select',
'value' => 'US',
),
array(
'name' => 'billing_address_1',
'type' => 'input',
'see' => 'input',
'value' => '123 Somewhere St',
),
array(
'name' => 'billing_address_2',
'type' => 'input',
'see' => 'input',
'value' => '',
),
array(
'name' => 'billing_city',
'type' => 'input',
'see' => 'input',
'value' => 'New York',
),
array(
'name' => 'billing_state',
'type' => 'select',
'see' => 'select',
'value' => 'NY',
),
array(
'name' => 'billing_postcode',
'type' => 'input',
'see' => 'input',
'value' => '12345',
),
array(
'name' => 'billing_phone',
'type' => 'input',
'see' => 'input',
'value' => '(555) 555-5555',
),
array(
'name' => 'billing_email',
'type' => 'input',
'see' => 'input',
'value' => 'testuser@example.com',
),
array(
'name' => 'order_comments',
'type' => 'textarea',
'see' => 'textarea',
'value' => 'This is an example comment.',
),
);
}
// Add any additional datasets here.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment