Skip to content

Commit

Permalink
Merge pull request #9341 from fatmaBouchekoua/selenium/identity.js
Browse files Browse the repository at this point in the history
Identity (Selenium tests)
  • Loading branch information
mbadrani committed Sep 25, 2018
2 parents d43e37b + 74a6f5f commit 8e2615f
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 10 deletions.
1 change: 1 addition & 0 deletions tests/E2E/package.json
Expand Up @@ -8,6 +8,7 @@
"start-selenium": "node_modules/selenium-standalone/bin/selenium-standalone start",
"high-test": "node_modules/mocha/bin/mocha test/campaigns/high/*",
"full-test": "node_modules/mocha/bin/mocha test/campaigns/full/*",
"selenium-test": "node_modules/mocha/bin/mocha test/campaigns/selenium/*",
"boom": "node_modules/mocha/bin/mocha test/campaigns/boom/*",
"test": "node_modules/mocha/bin/mocha test/campaigns/regular/*",
"install-upgrade-test": "node_modules/mocha/bin/mocha test/campaigns/install_upgrade/*",
Expand Down
155 changes: 155 additions & 0 deletions tests/E2E/prepare-shop.php
@@ -0,0 +1,155 @@
<?php
/**
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/

define('_PS_MODE_DEV_', false);
require(__DIR__.'/../../config/config.inc.php');

// useful variables

$language = Context::getContext()->language;
$shop = Context::getContext()->shop;
$dbPrefix = _DB_PREFIX_;

// Enable URL rewriting

function enableURLRewriting()
{
Configuration::updateValue('PS_REWRITING_SETTINGS', 1);
Tools::generateHtaccess();
}

if (!Configuration::get('PS_REWRITING_SETTINGS')) {
enableURLRewriting();
}

echo "- URL rewriting enabled\n";

//Enable returns

function enableReturns()
{
Configuration::updateValue('PS_ORDER_RETURN', 1);
}

if (!Configuration::get('PS_ORDER_RETURN')) {
enableReturns();
}

echo "- Returns enabled\n";

//Enable returns

function enableVouchers()
{
Configuration::updateValue('PS_CART_RULE_FEATURE_ACTIVE', 1);
}

if (!CartRule::isFeatureActive()) {
enableVouchers();
}

echo "- Vouchers enabled\n";

function enableGiftFeature()
{
Configuration::updateValue('PS_GIFT_WRAPPING', 1);
Configuration::updateValue('PS_GIFT_WRAPPING_PRICE', 5);
}

enableGiftFeature();


echo "- Gift feature display enabled\n";

// Setup modules

function disableModule($moduleName)
{
$module = Module::getInstanceByName($moduleName);
$module->disable();
echo "- module `$moduleName` disabled\n";
}

function hookModule($moduleName, $hookName)
{
$dbPrefix = _DB_PREFIX_;
$module = Module::getInstanceByName($moduleName);
$moduleId = $module->id;
Db::getInstance()->execute(
"DELETE FROM {$dbPrefix}hook_module WHERE id_module=$moduleId"
);
$module->registerHook($hookName);
echo "- module `$moduleName` hooked to `$hookName`\n";
}


// We need a customizable product: we add a single required text field to the product with id 1.

$customizableProduct = new Product(1, false, $language->id);

// Hijack the "_deleteOldLabels" method to remove existing labels
// (shouldn't be any but I want this script to be idempotent)
$refl = new ReflectionClass('Product');
$meth = $refl->getMethod('_deleteOldLabels');
$meth->setAccessible(true);
$meth->invoke($customizableProduct);

// First, create the label
$customizableProduct->createLabels(($fileFields = 0), ($textFields = 1));
$fields = $customizableProduct->getCustomizationFields();
$id_customization_field = current(current(current($fields)))['id_customization_field'];
// And inform the product that it has become customizable
$customizableProduct->customizable = 1;
$customizableProduct->text_fields = 1;
$customizableProduct->save();

// Then define it. There is unfortunately no API, so we encode the data in $_POST...
$_POST[implode('_', ['label', 1, $id_customization_field, $language->id, $shop->id])] = 'my field';
$_POST[implode('_', ['require', 1, $id_customization_field])] = true;
$customizableProduct->updateLabels();

echo "- added a required customizable text field to product #1\n";

// We need 2 languages for some tests
Language::checkAndAddLanguage('fr');
echo "- added French language just so that we have 2\n";
$languages = Language::getLanguages();
echo " Number of languages : ".count($languages)."\n";

$order = new Order(5);
$history = new OrderHistory();
$history->id_order = $order->id;
$history->id_employee = 1;

$use_existings_payment = false;
if (!$order->hasInvoice()) {
$use_existings_payment = true;
}
$history->changeIdOrderState(5, $order, $use_existings_payment);
$history->add();
echo "- Order number 5 is now delivered\n";

echo "Shop fixtures prepared for tests!\n";
12 changes: 12 additions & 0 deletions tests/E2E/test/campaigns/common_scenarios/customer.js
@@ -1,6 +1,8 @@
const {Menu} = require('../../selectors/BO/menu.js');
const {Customer} = require('../../selectors/BO/customers/customer');
const {accountPage} = require('../../selectors/FO/add_account_page');
const {productPage} = require('../../selectors/FO/product_page');
const {CheckoutOrderPage} = require('../../selectors/FO/order_page');
const {BO} = require('../../selectors/BO/customers/index');

let promise = Promise.resolve();
Expand Down Expand Up @@ -121,5 +123,15 @@ module.exports = {
test('should check the customer "Last name"', () => client.checkAttributeValue(accountPage.lastname_input, 'value', customerData.last_name));
test('should check that the customer "Email" is equal to "' + date_time + customerData.email_address + '"', () => client.checkAttributeValue(accountPage.email_input, 'value', date_time + customerData.email_address));
test('should check that the customer "Birthday" is equal to "' + customerData.birthday.month + '/' + customerData.birthday.day + '/' + customerData.birthday.year + '"', () => client.checkAttributeValue(accountPage.birthday_input, 'value', customerData.birthday.month + '/' + customerData.birthday.day + '/' + customerData.birthday.year, "contain"));
},
fillGuestInfo: function (message, client) {
test(message, () => {
return promise
.then(() => client.waitAndSetValue(accountPage.firstname_input, "I am"))
.then(() => client.waitAndSetValue(accountPage.lastname_input, "a Guest"))
.then(() => client.waitAndSetValue(accountPage.email_input, "guest@example.com"))
.then(() => client.waitForExistAndClick(accountPage.customer_form_continue_button))
.then(() => client.waitForVisible(accountPage.checkout_step_complete));
});
}
};
13 changes: 12 additions & 1 deletion tests/E2E/test/campaigns/common_scenarios/order.js
Expand Up @@ -33,7 +33,7 @@ module.exports = {
test('should set the "Last name" input', () => client.waitAndSetValue(accountPage.lastname_input, data.customer.lastname));
if (authentication === "create_account") {
test('should set the "Email" input', () => client.waitAndSetValue(accountPage.new_email_input, data.customer.email.replace("%ID", date_time)));
test('should set the "Password" input', () => client.waitAndSetValue(accountPage.new_password_input, data.customer.password));
test('should set the "Password" input', () => client.waitAndSetValue(accountPage.password_account_input, data.customer.password));
} else {
test('should set the "Email" input', () => client.waitAndSetValue(accountPage.new_email_input, data.customer.email.replace("%ID", '_guest' + date_time)));
}
Expand Down Expand Up @@ -194,5 +194,16 @@ module.exports = {
test('should compare both informations', () => client.checkExportedFileInfo(1000));
test('should reset filter', () => client.waitForExistAndClick(ShoppingCart.reset_button));
}, 'order', true);
},
initCheckout: function (client) {
test('should add some product to cart"', () => {
return promise
.then(() => client.waitForExistAndClick(productPage.cloths_category))
.then(() => client.waitForExistAndClick(productPage.second_product_clothes_category))
.then(() => client.waitForExistAndClick(CheckoutOrderPage.add_to_cart_button))
.then(() => client.waitForVisible(CheckoutOrderPage.blockcart_modal))
.then(() => client.waitForVisibleAndClick(CheckoutOrderPage.proceed_to_checkout_modal_button))
.then(() => client.waitForExistAndClick(CheckoutOrderPage.proceed_to_checkout_button));
});
}
};
117 changes: 117 additions & 0 deletions tests/E2E/test/campaigns/selenium/identity.js
@@ -0,0 +1,117 @@
const {AccessPageFO} = require('../../selectors/FO/access_page');
const {accountPage} = require('../../selectors/FO/add_account_page');
const customer = require('../common_scenarios/customer');
const order = require('../common_scenarios/order');
let promise = Promise.resolve();

scenario('Customer Identity', () => {
scenario('Open the browser and access to the FO', client => {
test('should open the browser', () => client.open());
test('should access to FO', () => client.accessToFO(AccessPageFO));
test('should change the FO language to english', () => client.changeLanguage());
}, 'customer');
scenario('The Customer Identity Page', client => {
test('should show the customer form', () => {
return promise
.then(() => client.scrollWaitForExistAndClick(AccessPageFO.personal_info, 150, 2000))
.then(() => client.waitAndSetValue(accountPage.signin_email_input, "pub@prestashop.com"))
.then(() => client.waitAndSetValue(accountPage.signin_password_input, "123456789"))
.then(() => client.waitForExistAndClick(AccessPageFO.login_button))
.then(() => client.isVisible(accountPage.customer_form))
.then(() => expect(global.isVisible).to.be.true);
});
test('should refuse to save the customer if the wrong password is provided', () => {
return promise
.then(() => client.waitAndSetValue(accountPage.password_account_input, "wrongPassword"))
.then(() => client.waitForVisibleAndClick(accountPage.save_account_button))
.then(() => client.waitForVisible(accountPage.danger_alert))
});
test('should save the customer if the correct password is provided', () => {
return promise
.then(() => client.waitAndSetValue(accountPage.password_account_input, "123456789"))
.then(() => client.waitForExistAndClick(accountPage.save_account_button))
.then(() => client.waitForVisible(accountPage.success_alert));
});
test('should allow the customer to change their password', () => {
return promise
.then(() => client.waitAndSetValue(accountPage.password_account_input, "123456789"))
.then(() => client.waitAndSetValue(accountPage.new_password_input, "newPassword"))
.then(() => client.waitForExistAndClick(accountPage.save_account_button))
.then(() => client.waitForVisible(accountPage.success_alert));
});
test('should allow the customer to use the new password', () => {
return promise
.then(() => client.waitForExistAndClick(AccessPageFO.sign_out_button))
.then(() => client.waitAndSetValue(accountPage.signin_email_input, "pub@prestashop.com"))
.then(() => client.waitAndSetValue(accountPage.signin_password_input, "newPassword"))
.then(() => client.waitForExistAndClick(AccessPageFO.login_button))
.then(() => client.waitAndSetValue(accountPage.password_account_input, "newPassword"))
.then(() => client.waitAndSetValue(accountPage.new_password_input, "123456789"))
.then(() => client.waitForExistAndClick(accountPage.save_account_button))
.then(() => client.waitForVisible(accountPage.success_alert));
});
test('should logout', () => {
return promise
.then(() => client.waitForExistAndClick(AccessPageFO.sign_out_button))
.then(() => client.waitForExistAndClick(AccessPageFO.logo_home_page))
.then(() => client.changeLanguage());
});
}, 'customer');

scenario('The guest form during checkout', () => {
scenario('Add product to cart as a guest', client => {
order.initCheckout(client);
}, 'order');

scenario('the form can be filled a first time with an email address', client => {
customer.fillGuestInfo('Fill the personal information step as a guest', client);
}, 'customer');

scenario('there can be 2 guests using the same e-mail address', () => {
scenario('Delete cookies', client => {
test('should delete cookies', () => client.deleteCookie());
test('should click on "Continue shopping', () => client.waitForExistAndClick(accountPage.continue_shopping));
}, 'customer');
scenario('Add product to cart as a guest', client => {
order.initCheckout(client);
}, 'order');
scenario('should let another guest use the same e-mail address', client => {
customer.fillGuestInfo('should let another guest use the same e-mail address', client);
}, 'customer');
}, 'customer');

scenario('Updating the guest account during checkout', client => {
test('should let the guest update their lastname', () => {
return promise
.then(() => client.waitForExistAndClick(accountPage.checkout_step))
.then(() => client.waitAndSetValue(accountPage.lastname_input, "a Ghost"))
.then(() => client.waitForExistAndClick(accountPage.customer_form_continue_button))
.then(() => client.waitForVisible(accountPage.checkout_step_complete));
});
test('should not let the guest change their email address to that of a real customer', () => {
return promise
.then(() => client.waitForExistAndClick(accountPage.checkout_step))
.then(() => client.waitAndSetValue(accountPage.email_input, "pub@prestashop.com"))
.then(() => client.waitForExistAndClick(accountPage.customer_form_continue_button))
.then(() => client.isNotExisting(accountPage.checkout_step_complete));
});
test('should let the guest change their email address if not used by a customer', () => {
return promise
.then(() => client.waitAndSetValue(accountPage.email_input, "guest.guest@example.com"))
.then(() => client.waitForExistAndClick(accountPage.customer_form_continue_button))
.then(() => client.waitForVisible(accountPage.checkout_step_complete));
});
test('should let the guest add a password to create an account', () => {
return promise
.then(() => client.waitForExistAndClick(accountPage.checkout_step))
.then(() => client.waitAndSetValue(accountPage.email_input, "test" + date_time + "@example.com"))
.then(() => client.waitAndSetValue(accountPage.password_account_input, "123456789"))
.then(() => client.waitForExistAndClick(accountPage.customer_form_continue_button))
.then(() => client.waitForVisible(accountPage.checkout_step_complete))
.then(() => client.waitForExistAndClick(accountPage.checkout_step))
.then(() => client.isExisting(accountPage.checkout_step))

});
}, 'customer');
}, 'customer');
}, 'customer', true);
4 changes: 3 additions & 1 deletion tests/E2E/test/clients/common_client.js
Expand Up @@ -505,6 +505,7 @@ class CommonClient {
return deca[Math.floor(number / 10) - 2] + 'y-' + special[number % 10];
}


/**
* This function searches the data in the table in case a filter input exists
* @param selector
Expand Down Expand Up @@ -538,8 +539,9 @@ class CommonClient {
}
}

refresh() {
deleteCookie() {
return this.client
.deleteCookie()
.refresh();
}

Expand Down
2 changes: 1 addition & 1 deletion tests/E2E/test/clients/customer.js
Expand Up @@ -36,4 +36,4 @@ class Customer extends CommonClient {

}

module.exports = Customer;
module.exports = Customer;
3 changes: 2 additions & 1 deletion tests/E2E/test/selectors/FO/access_page.js
Expand Up @@ -47,6 +47,7 @@ module.exports = {
display_top_link_widget:'//*[@id="header"]/div[2]/div/div[1]/div[2]/div[3]/div//p[contains(text(),"%DISPLAYTOP")]',
second_display_top_link_widget:'//*[@id="header"]/div[2]/div/div[1]/div[2]/div[3]/div/div[2]/p',
not_found_error_message: '//*[@id="main"]//h1',
product_name: '//*[@id="js-product-list"]//h2//a[contains(text(),"%PAGENAME")]'
product_name: '//*[@id="js-product-list"]//h2//a[contains(text(),"%PAGENAME")]',
personal_info: '//*[@id="footer_account_list"]//a[@title="Personal info"]'
}
};

0 comments on commit 8e2615f

Please sign in to comment.