Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mescalantea committed Jan 31, 2025
1 parent 6b30aca commit 7e9fa94
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export default defineConfig({

/* Configure projects for major browsers */
projects: [
{
name: 'checkout-product',
use: { ...devices['Desktop Chrome'] },
testMatch: '001-checkout-product.spec.js',
},
{
name: 'configuration-payment-methods',
use: { ...devices['Desktop Chrome'] },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BackOffice } from 'playwright-fixture-for-plugins';
export default class MagentoBackOffice extends BackOffice {
import { BackOffice as BaseBackOffice } from 'playwright-fixture-for-plugins';
export default class BackOffice extends BaseBackOffice {

/**
* Init the locators with the locators available
Expand Down
117 changes: 117 additions & 0 deletions tests-e2e/fixtures/pages/CheckoutPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { CheckoutPage as BaseCheckoutPage } from "playwright-fixture-for-plugins";

/**
* Checkout page
*/
export default class CheckoutPage extends BaseCheckoutPage {

/**
* Init the locators with the locators available
*
* @returns {Object}
*/
initLocators() {
return {
// ...super.initLocators(),
// messageSuccess: () => this.page.locator('.message-success'),
loader: () => this.page.locator('.loading-mask', { state: 'visible' }),
email: () => this.page.locator('#customer-email'),
firstName: () => this.page.locator('[name=firstname]'),
lastName: () => this.page.locator('[name=lastname]'),
// locator for selector [name="street[0]"]
address1: () => this.page.locator('[name="street[0]"]'),
country: () => this.page.locator('[name=country_id]'),
state: () => this.page.locator('[name=region_id]'),
city: () => this.page.locator('[name=city]'),
postcode: () => this.page.locator('[name=postcode]'),
phone: () => this.page.locator('[name=telephone]'),
flatRateShipping: () => this.page.locator('[value="flatrate_flatrate"]'),
continueButton: () => this.page.locator('.action.continue'),
};
}

/**
* Provide the checkout URL
* @param {Object} options
* @returns {string} The checkout URL
*/
checkoutUrl(options = {}) {
return `${this.baseURL}/checkout/`;
}

/**
* Fill the checkout page's form
* @param {Object} options Contains the data to fill the form
* @param {string} options.email Email
* @param {string} options.firstName First name
* @param {string} options.lastName Last name
* @param {string} options.address1 Address first line
* @param {string} options.country Typically a 2-letter ISO country code
* @param {string} options.state Name of the state
* @param {string} options.city Name of the city
* @param {string} options.postcode Postcode
* @param {string} options.phone Phone number
* @param {string} options.shippingMethod Shipping method
* @returns {Promise<void>}
*/
async fillForm(options) {
await this.fillShippingForm(options);
await this.selectShippingMethod(options);
await this.locators.continueButton().click();
// TODO: Implement the form filling
}

/**
* Fill the shipping form
* @param {Object} options
* @param {string} options.email Email
* @param {string} options.firstName First name
* @param {string} options.lastName Last name
* @param {string} options.address1 Address first line
* @param {string} options.country Typically a 2-letter ISO country code
* @param {string} options.state Name of the state
* @param {string} options.city Name of the city
* @param {string} options.postcode Postcode
* @param {string} options.phone Phone number
* @returns {Promise<void>}
*/
async fillShippingForm(options) {
await this.page.waitForURL(/#shipping/);
await this.#waitForFinishLoading();
const { email, firstName, lastName, address1, country, state, city, postcode, phone } = options;
// TODO: Implement the form filling
await this.locators.email().fill(email);
await this.locators.firstName().fill(firstName);
await this.locators.lastName().fill(lastName);
await this.locators.address1().fill(address1);
await this.locators.country().selectOption(country);
await this.locators.state().selectOption({ label: state });
await this.locators.city().fill(city);
await this.locators.postcode().fill(postcode);
await this.locators.phone().fill(phone);
}

/**
* Select the shipping method
* @param {Object} options
* @param {string} options.shippingMethod Shipping method
* @returns {Promise<void>}
*/
async selectShippingMethod(options) {
await this.page.waitForURL(/#shipping/);
const { shippingMethod } = options;
// TODO: Implement the method selection
await this.#waitForFinishLoading();
this.locators.flatRateShipping().click();
}

/**
* Wait for the checkout to finish loading
* @returns {Promise<void>}
*/
async #waitForFinishLoading() {
do {
await this.expect(this.locators.loader().first()).toBeHidden();
} while ((await this.locators.loader()) > 0);
}
}
58 changes: 58 additions & 0 deletions tests-e2e/fixtures/pages/ProductPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ProductPage as BaseProductPage } from "playwright-fixture-for-plugins";

/**
* Product page
*/
export default class ProductPage extends BaseProductPage {

/**
* Init the locators with the locators available
*
* @returns {Object}
*/
initLocators() {
return {
...super.initLocators(),
messageSuccess: () => this.page.locator('.message-success'),
};
}

/**
* Provide the product URL
* @param {Object} options
* @param {string} options.slug The product slug
* @returns {string} The product URL
*/
productUrl(options) {
const { slug } = options;
return `${this.baseURL}/${slug}.html`;
}

/**
* Provide the locator for the quantity input
*
* @param {Object} options
* @returns {import("@playwright/test").Locator}
*/
qtyLocator(options = {}) {
return this.page.locator('#qty');
}
/**
* Provide the locator for adding to cart button
*
* @param {Object} options
* @returns {import("@playwright/test").Locator}
*/
addToCartLocator(options = {}) {
return this.page.locator('#product-addtocart-button');
}

/**
* Wait for the product to be in the cart
* @param {Object} options
* @returns {Promise<void>}
*/
async expectProductIsInCart(options = {}) {
await this.locators.messageSuccess().waitFor({timeout: 10000});
}
}
15 changes: 10 additions & 5 deletions tests-e2e/fixtures/test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { test as baseTest, expect } from "@playwright/test";
import { PaymentMethodsSettingsPage } from "playwright-fixture-for-plugins";
import MagentoBackOffice from "./MagentoBackOffice";
import MagentoSeQuraHelper from "./MagentoSeQuraHelper";
import { DataProvider, PaymentMethodsSettingsPage } from "playwright-fixture-for-plugins";
import BackOffice from "./base/BackOffice";
import SeQuraHelper from "./utils/SeQuraHelper";
import ProductPage from "./pages/ProductPage";
import CheckoutPage from "./pages/CheckoutPage";

const test = baseTest.extend({
backOffice: async ({ page, baseURL }, use) => await use(new MagentoBackOffice(page, baseURL, expect)),
helper: async ({ page, baseURL, request }, use) => await use(new MagentoSeQuraHelper(page, baseURL, expect, request)),
dataProvider: async ({ page, baseURL }, use) => await use(new DataProvider(page, baseURL, expect)),
backOffice: async ({ page, baseURL }, use) => await use(new BackOffice(page, baseURL, expect)),
helper: async ({ page, baseURL, request }, use) => await use(new SeQuraHelper(page, baseURL, expect, request)),
paymentMethodsSettingsPage: async ({ page, baseURL, request, backOffice, helper}, use) => await use(new PaymentMethodsSettingsPage(page, baseURL, expect, request, backOffice, helper)),
productPage: async ({ page, baseURL, request}, use) => await use(new ProductPage(page, baseURL, expect, request)),
checkoutPage: async ({ page, baseURL, request}, use) => await use(new CheckoutPage(page, baseURL, expect, request)),
});

test.afterEach(async ({ page }, testInfo) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SeQuraHelper } from 'playwright-fixture-for-plugins';
import { SeQuraHelper as BaseSeQuraHelper } from 'playwright-fixture-for-plugins';

export default class MagentoSeQuraHelper extends SeQuraHelper {
export default class SeQuraHelper extends BaseSeQuraHelper {

/**
* Init the webhooks available
Expand Down
67 changes: 67 additions & 0 deletions tests-e2e/specs/001-checkout-product.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { test } from '../fixtures/test';

test.describe('Product checkout', () => {

test('All available seQura products appear in the checkout', async ({ helper, dataProvider, productPage, checkoutPage }) => {
// Setup
const { dummy_config } = helper.webhooks;
const shopper = dataProvider.shopper();
await helper.executeWebhook({ webhook: dummy_config }); // Setup for physical products.

// Execution
await productPage.addToCart({ slug: 'push-it-messenger-bag', quantity: 1 });
await checkoutPage.goto();
await checkoutPage.fillForm(shopper);
// --

// await productPage.addToCart({ slug: 'sunglasses', quantity: 1 });

// const helper = new SeQuraHelper(request, expect);
// for (const version of ['classic', 'blocks']) {
// await helper.executeWebhook({ webhook: helper.webhooks.CHECKOUT_VERSION, args: [{ name: 'version', value: version }] });
// await checkoutPage.goto();
// if (version === 'blocks') {
// await checkoutPage.expectPaymentMethodsBeingReloaded();
// }
// await checkoutPage.expectI1ToBeVisible();
// await checkoutPage.expectSp1ToBeVisible();
// await checkoutPage.expectPp3ToBeVisible();
// await checkoutPage.expectEducationPopupToWork('100.00');
// }
});

// test('Make a successful payment using any shopper name', async ({ productPage, checkoutPage }) => {
// await checkoutPage.setupForPhysicalProducts();
// await productPage.addToCart({ slug: 'sunglasses', quantity: 1 });

// await checkoutPage.goto();
// await checkoutPage.fillWithNonSpecialShopperName({});
// await checkoutPage.expectPaymentMethodsBeingReloaded();
// await checkoutPage.placeOrderUsingI1({ shopper: 'nonSpecial' });
// await checkoutPage.waitForOrderSuccess();
// });

// test('Make a 🍊 payment with "Review test approve" names', async ({ productPage, checkoutPage }) => {
// await checkoutPage.setupForPhysicalProducts();
// await productPage.addToCart({ slug: 'sunglasses', quantity: 1 });

// await checkoutPage.goto();
// await checkoutPage.fillWithReviewTest({});
// await checkoutPage.expectPaymentMethodsBeingReloaded();
// await checkoutPage.placeOrderUsingI1({});
// await checkoutPage.waitForOrderOnHold();
// await checkoutPage.expectOrderChangeTo({ toStatus: 'wc-processing' });
// });

// test('Make a 🍊 payment with "Review test cancel" names', async ({ productPage, checkoutPage }) => {
// await checkoutPage.setupForPhysicalProducts();
// await productPage.addToCart({ slug: 'sunglasses', quantity: 1 });

// await checkoutPage.goto();
// await checkoutPage.fillWithReviewTest({ shopper: 'cancel' });
// await checkoutPage.expectPaymentMethodsBeingReloaded();
// await checkoutPage.placeOrderUsingI1({});
// await checkoutPage.waitForOrderOnHold();
// await checkoutPage.expectOrderChangeTo({ toStatus: 'wc-cancelled' });
// });
});
9 changes: 2 additions & 7 deletions tests-e2e/specs/004-configuration-payment-methods.spec.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import { test } from '../fixtures/test';

test.describe('Configuration', () => {
test('Payment methods', async ({ helper, paymentMethodsSettingsPage }) => {
test('Payment methods', async ({ helper, dataProvider, paymentMethodsSettingsPage }) => {
// Setup
const { dummy_config } = helper.webhooks;
const countries = [
{ name: 'Spain', paymentMethods: ['Paga Después', 'Divide tu pago en 3', 'Paga Fraccionado'] },
{ name: 'France', paymentMethods: ['Payez en plusieurs fois'] },
{ name: 'Italy', paymentMethods: ['Pagamento a rate'] },
{ name: 'Portugal', paymentMethods: ['Pagamento Fracionado'] }
];
const countries = dataProvider.countriesPaymentMethods();
// Execution
await helper.executeWebhook({ webhook: dummy_config });
await paymentMethodsSettingsPage.goto();
Expand Down

0 comments on commit 7e9fa94

Please sign in to comment.