Last active
March 7, 2019 14:22
-
-
Save norcross/4d45f1902bfb2f1f4cf79997a47d9d03 to your computer and use it in GitHub Desktop.
Run various acceptance tests for WooCommerce
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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' => '[email protected]', | |
), | |
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