Added new tests to wp-admin-order-edit.test.js for covering merchant management actions over downloadable products. (#31650)
* Added new tests to wp-admin-order-edit.test.js for covering merchant management actions over downloadable products. * Updated changelogs from e2e-utils and e2e-core packages. * - Fixed minor issue from wp-admin-order-edit.test.js when running tests in browser mode. - Changed those tests so that products and orders are deleted individually after every test run. - Added deleteOrder() and deleteProduct() functions to withRestApi. Co-authored-by: rodelgc <rodel.calasagsag@automattic.com>
This commit is contained in:
parent
d68b6d7777
commit
5af5be5100
|
@ -2,16 +2,20 @@
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
- Updated assertion in the block `can update order details` from the e2e test `order-edit.test.js` that wasn't checking properly the date value when editing an order, allowing the test to return a false positive.
|
||||||
- Moved `merchant.login()` out of `beforeAll()` block and into test body for retried runs.
|
- Moved `merchant.login()` out of `beforeAll()` block and into test body for retried runs.
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
- Additional Merchant Order Edit tests to increase the downloadable products coverage.
|
||||||
- A `specs/data` folder to store page element data.
|
- A `specs/data` folder to store page element data.
|
||||||
- Tests to verify that different top-level menus and their associated sub-menus load successfully.
|
- Tests to verify that different top-level menus and their associated sub-menus load successfully.
|
||||||
- Test scaffolding via `npx wc-e2e install @woocommerce/e2e-core-tests`
|
- Test scaffolding via `npx wc-e2e install @woocommerce/e2e-core-tests`
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
- The e2e test `update-product-settings.test.js` now covers setting and unsetting the `X-Accel-Redirect/X-Sendfile` download method and `Append a unique string to filename for security` flag.
|
||||||
|
- The e2e test `order-edit.test.js` now uses the API to create orders.
|
||||||
- New coupon test deletes the coupon instead of trashing it.
|
- New coupon test deletes the coupon instead of trashing it.
|
||||||
- A copy of sample_data.csv is included in the package.
|
- A copy of sample_data.csv is included in the package.
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,30 @@
|
||||||
*/
|
*/
|
||||||
const {
|
const {
|
||||||
merchant,
|
merchant,
|
||||||
createSimpleOrder,
|
|
||||||
withRestApi,
|
withRestApi,
|
||||||
utils,
|
utils,
|
||||||
|
createSimpleDownloadableProduct,
|
||||||
|
createOrder,
|
||||||
|
verifyValueOfInputField,
|
||||||
|
orderPageSaveChanges,
|
||||||
} = require( '@woocommerce/e2e-utils' );
|
} = require( '@woocommerce/e2e-utils' );
|
||||||
|
|
||||||
let orderId;
|
let orderId;
|
||||||
|
|
||||||
|
const orderStatus = {
|
||||||
|
processing: 'processing',
|
||||||
|
completed: 'completed'
|
||||||
|
};
|
||||||
|
|
||||||
const runEditOrderTest = () => {
|
const runEditOrderTest = () => {
|
||||||
describe('WooCommerce Orders > Edit order', () => {
|
describe('WooCommerce Orders > Edit order', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
orderId = await createOrder( { status: orderStatus.processing } );
|
||||||
await merchant.login();
|
await merchant.login();
|
||||||
orderId = await createSimpleOrder('Processing');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll( async () => {
|
afterAll( async () => {
|
||||||
await withRestApi.deleteAllOrders();
|
await withRestApi.deleteOrder( orderId );
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can view single order', async () => {
|
it('can view single order', async () => {
|
||||||
|
@ -69,14 +77,158 @@ const runEditOrderTest = () => {
|
||||||
await utils.waitForTimeout( 2000 );
|
await utils.waitForTimeout( 2000 );
|
||||||
|
|
||||||
// Save the order changes
|
// Save the order changes
|
||||||
await expect( page ).toClick( 'button.save_order' );
|
await orderPageSaveChanges();
|
||||||
await page.waitForSelector( '#message' );
|
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
await expect( page ).toMatchElement( '#message', { text: 'Order updated.' } );
|
await expect( page ).toMatchElement( '#message', { text: 'Order updated.' } );
|
||||||
await expect( page ).toMatchElement( 'input[name=order_date]', { value: '2018-12-14' } );
|
await verifyValueOfInputField( 'input[name=order_date]' , '2018-12-14' );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe( 'WooCommerce Orders > Edit order > Downloadable product permissions', () => {
|
||||||
|
const productName = 'TDP 001';
|
||||||
|
const customerBilling = {
|
||||||
|
email: 'john.doe@example.com',
|
||||||
|
};
|
||||||
|
|
||||||
|
let productId;
|
||||||
|
|
||||||
|
beforeAll( async () => {
|
||||||
|
await merchant.login();
|
||||||
|
} );
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
productId = await createSimpleDownloadableProduct( productName );
|
||||||
|
orderId = await createOrder( {
|
||||||
|
productId,
|
||||||
|
customerBilling ,
|
||||||
|
status: orderStatus.processing
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
afterEach( async () => {
|
||||||
|
await withRestApi.deleteOrder( orderId );
|
||||||
|
await withRestApi.deleteProduct( productId );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can add downloadable product permissions to order without product', async () => {
|
||||||
|
// Create order without product
|
||||||
|
const newOrderId = await createOrder( {
|
||||||
|
customerBilling,
|
||||||
|
status: orderStatus.processing
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( newOrderId );
|
||||||
|
|
||||||
|
// Add permission
|
||||||
|
await merchant.addDownloadableProductPermission( productName );
|
||||||
|
|
||||||
|
// Verify new downloadable product permission details
|
||||||
|
await merchant.verifyDownloadableProductPermission( productName )
|
||||||
|
|
||||||
|
// Remove order
|
||||||
|
await withRestApi.deleteOrder( newOrderId );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can add downloadable product permissions to order with product', async () => {
|
||||||
|
// Create new downloadable product
|
||||||
|
const newProductName = 'TDP 002';
|
||||||
|
const newProductId = await createSimpleDownloadableProduct( newProductName );
|
||||||
|
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
|
||||||
|
// Add permission
|
||||||
|
await merchant.addDownloadableProductPermission( newProductName );
|
||||||
|
|
||||||
|
// Verify new downloadable product permission details
|
||||||
|
await merchant.verifyDownloadableProductPermission( newProductName )
|
||||||
|
|
||||||
|
// Remove product
|
||||||
|
await withRestApi.deleteProduct( newProductId );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can edit downloadable product permissions', async () => {
|
||||||
|
// Define expected downloadable product attributes
|
||||||
|
const expectedDownloadsRemaining = '10';
|
||||||
|
const expectedDownloadsExpirationDate = '2050-01-01';
|
||||||
|
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
|
||||||
|
// Update permission
|
||||||
|
await merchant.updateDownloadableProductPermission(
|
||||||
|
productName,
|
||||||
|
expectedDownloadsExpirationDate,
|
||||||
|
expectedDownloadsRemaining
|
||||||
|
);
|
||||||
|
|
||||||
|
// Verify new downloadable product permission details
|
||||||
|
await merchant.verifyDownloadableProductPermission(
|
||||||
|
productName,
|
||||||
|
expectedDownloadsExpirationDate,
|
||||||
|
expectedDownloadsRemaining
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can revoke downloadable product permissions', async () => {
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
|
||||||
|
// Revoke permission
|
||||||
|
await merchant.revokeDownloadableProductPermission( productName );
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
await expect( page ).not.toMatchElement( 'div.order_download_permissions', {
|
||||||
|
text: productName
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should not allow downloading a product if download attempts are exceeded', async () => {
|
||||||
|
// Define expected download error reason
|
||||||
|
const expectedReason = 'Sorry, you have reached your download limit for this file';
|
||||||
|
|
||||||
|
// Create order with product without any available download attempt
|
||||||
|
const newProductId = await createSimpleDownloadableProduct( productName, 0 );
|
||||||
|
const newOrderId = await createOrder( {
|
||||||
|
productId: newProductId,
|
||||||
|
customerBilling,
|
||||||
|
status: orderStatus.processing
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( newOrderId );
|
||||||
|
|
||||||
|
// Open download page
|
||||||
|
const downloadPage = await merchant.openDownloadLink();
|
||||||
|
|
||||||
|
// Verify file download cannot start
|
||||||
|
await merchant.verifyCannotDownloadFromBecause( downloadPage, expectedReason );
|
||||||
|
|
||||||
|
// Remove data
|
||||||
|
await withRestApi.deleteOrder( newOrderId );
|
||||||
|
await withRestApi.deleteProduct( newProductId );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should not allow downloading a product if expiration date is exceeded', async () => {
|
||||||
|
// Define expected download error reason
|
||||||
|
const expectedReason = 'Sorry, this download has expired';
|
||||||
|
|
||||||
|
// Open order we created
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
|
||||||
|
// Update permission so that the expiration date has already passed
|
||||||
|
// Note: Seems this operation can't be performed through the API
|
||||||
|
await merchant.updateDownloadableProductPermission( productName, '2018-12-14' );
|
||||||
|
|
||||||
|
// Open download page
|
||||||
|
const downloadPage = await merchant.openDownloadLink();
|
||||||
|
|
||||||
|
// Verify file download cannot start
|
||||||
|
await merchant.verifyCannotDownloadFromBecause( downloadPage, expectedReason );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = runEditOrderTest;
|
module.exports = runEditOrderTest;
|
||||||
|
|
|
@ -29,6 +29,7 @@ const runProductSettingsTest = () => {
|
||||||
await setCheckbox('#woocommerce_downloads_require_login');
|
await setCheckbox('#woocommerce_downloads_require_login');
|
||||||
await setCheckbox('#woocommerce_downloads_grant_access_after_payment');
|
await setCheckbox('#woocommerce_downloads_grant_access_after_payment');
|
||||||
await setCheckbox('#woocommerce_downloads_redirect_fallback_allowed');
|
await setCheckbox('#woocommerce_downloads_redirect_fallback_allowed');
|
||||||
|
await unsetCheckbox('#woocommerce_downloads_add_hash_to_filename');
|
||||||
await settingsPageSaveChanges();
|
await settingsPageSaveChanges();
|
||||||
|
|
||||||
// Verify that settings have been saved
|
// Verify that settings have been saved
|
||||||
|
@ -38,22 +39,35 @@ const runProductSettingsTest = () => {
|
||||||
verifyCheckboxIsSet('#woocommerce_downloads_require_login'),
|
verifyCheckboxIsSet('#woocommerce_downloads_require_login'),
|
||||||
verifyCheckboxIsSet('#woocommerce_downloads_grant_access_after_payment'),
|
verifyCheckboxIsSet('#woocommerce_downloads_grant_access_after_payment'),
|
||||||
verifyCheckboxIsSet('#woocommerce_downloads_redirect_fallback_allowed'),
|
verifyCheckboxIsSet('#woocommerce_downloads_redirect_fallback_allowed'),
|
||||||
|
verifyCheckboxIsUnset('#woocommerce_downloads_add_hash_to_filename')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await page.reload();
|
await page.reload();
|
||||||
await expect(page).toSelect('#woocommerce_file_download_method', 'Force downloads');
|
await expect(page).toSelect('#woocommerce_file_download_method', 'X-Accel-Redirect/X-Sendfile');
|
||||||
await unsetCheckbox('#woocommerce_downloads_require_login');
|
await unsetCheckbox('#woocommerce_downloads_require_login');
|
||||||
await unsetCheckbox('#woocommerce_downloads_grant_access_after_payment');
|
await unsetCheckbox('#woocommerce_downloads_grant_access_after_payment');
|
||||||
await unsetCheckbox('#woocommerce_downloads_redirect_fallback_allowed');
|
await unsetCheckbox('#woocommerce_downloads_redirect_fallback_allowed');
|
||||||
|
await setCheckbox('#woocommerce_downloads_add_hash_to_filename');
|
||||||
await settingsPageSaveChanges();
|
await settingsPageSaveChanges();
|
||||||
|
|
||||||
// Verify that settings have been saved
|
// Verify that settings have been saved
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
expect(page).toMatchElement('#message', {text: 'Your settings have been saved.'}),
|
expect(page).toMatchElement('#message', {text: 'Your settings have been saved.'}),
|
||||||
expect(page).toMatchElement('#woocommerce_file_download_method', {text: 'Force downloads'}),
|
expect(page).toMatchElement('#woocommerce_file_download_method', {text: 'X-Accel-Redirect/X-Sendfile'}),
|
||||||
verifyCheckboxIsUnset('#woocommerce_downloads_require_login'),
|
verifyCheckboxIsUnset('#woocommerce_downloads_require_login'),
|
||||||
verifyCheckboxIsUnset('#woocommerce_downloads_grant_access_after_payment'),
|
verifyCheckboxIsUnset('#woocommerce_downloads_grant_access_after_payment'),
|
||||||
verifyCheckboxIsUnset('#woocommerce_downloads_redirect_fallback_allowed'),
|
verifyCheckboxIsUnset('#woocommerce_downloads_redirect_fallback_allowed'),
|
||||||
|
verifyCheckboxIsSet('#woocommerce_downloads_add_hash_to_filename')
|
||||||
|
]);
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await expect(page).toSelect('#woocommerce_file_download_method', 'Force downloads');
|
||||||
|
await settingsPageSaveChanges();
|
||||||
|
|
||||||
|
// Verify that settings have been saved
|
||||||
|
await Promise.all([
|
||||||
|
expect(page).toMatchElement('#message', {text: 'Your settings have been saved.'}),
|
||||||
|
expect(page).toMatchElement('#woocommerce_file_download_method', {text: 'Force downloads'})
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- `createSimpleDownloadableProduct` component which creates a simple downloadable product, containing four parameters for title, price, download name and download limit.
|
||||||
|
- `orderPageSaveChanges()` to save changes in the order page.
|
||||||
|
- `getSelectorAttribute( selector, attribute )` to retrieve the desired HTML attribute from an element.
|
||||||
|
- `verifyValueOfElementAttribute( selector, attribute, expectedValue )` to check that a specific HTML attribute from an element matches the expected value.
|
||||||
|
- `withRestApi.deleteProduct()` that deletes a single product.
|
||||||
|
- `withRestApi.deleteOrder()` that deletes a single order.
|
||||||
|
- `merchant.addDownloadableProductPermission()` to add a downloadable product permission to an order.
|
||||||
|
- `merchant.updateDownloadableProductPermission()` to update the attributes of an existing downloadable product permission.
|
||||||
|
- `merchant.revokeDownloadableProductPermission()` to remove the existing downloadable product permission from an order.
|
||||||
|
- `merchant.verifyDownloadableProductPermission()` to check that the attributes of an existing downloadable product permission are correct.
|
||||||
|
- `merchant.openDownloadLink()` to open the url of a download in a new tab.
|
||||||
|
- `merchant.verifyCannotDownloadFromBecause()` to check that a download cannot happen for a specific reason.
|
||||||
|
|
||||||
|
# 0.1.7
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- Identified the default product category using `slug == 'uncategorized'` in `deleteAllProductCategories`
|
- Identified the default product category using `slug == 'uncategorized'` in `deleteAllProductCategories`
|
||||||
|
|
|
@ -84,6 +84,7 @@ This package provides support for enabling retries in tests:
|
||||||
|
|
||||||
| Function | Parameters | Description |
|
| Function | Parameters | Description |
|
||||||
|----------|-------------|------------|
|
|----------|-------------|------------|
|
||||||
|
| `addDownloadableProductPermission` | `productName` | Add a downloadable permission for product in order |
|
||||||
| `collapseAdminMenu` | `collapse` | Collapse or expand the WP admin menu |
|
| `collapseAdminMenu` | `collapse` | Collapse or expand the WP admin menu |
|
||||||
| `dismissOnboardingWizard` | | Dismiss the onboarding wizard if present |
|
| `dismissOnboardingWizard` | | Dismiss the onboarding wizard if present |
|
||||||
| `goToOrder` | `orderId` | Go to view a single order |
|
| `goToOrder` | `orderId` | Go to view a single order |
|
||||||
|
@ -107,11 +108,16 @@ This package provides support for enabling retries in tests:
|
||||||
| `openImportProducts` | | Open the Import Products page |
|
| `openImportProducts` | | Open the Import Products page |
|
||||||
| `openExtensions` | | Go to WooCommerce -> Extensions |
|
| `openExtensions` | | Go to WooCommerce -> Extensions |
|
||||||
| `openWordPressUpdatesPage` | | Go to Dashboard -> Updates |
|
| `openWordPressUpdatesPage` | | Go to Dashboard -> Updates |
|
||||||
|
| `revokeDownloadableProductPermission` | `productName` | Remove a downloadable product permission from order |
|
||||||
| `installAllUpdates` | | Install all pending updates on Dashboard -> Updates|
|
| `installAllUpdates` | | Install all pending updates on Dashboard -> Updates|
|
||||||
|
| `updateDownloadableProductPermission` | `productName, expirationDate, downloadsRemaining` | Update the attributes of a downloadable product permission in order |
|
||||||
| `updateWordPress` | | Install pending WordPress updates on Dashboard -> Updates|
|
| `updateWordPress` | | Install pending WordPress updates on Dashboard -> Updates|
|
||||||
| `updatePlugins` | | Install all pending plugin updates on Dashboard -> Updates|
|
| `updatePlugins` | | Install all pending plugin updates on Dashboard -> Updates|
|
||||||
| `updateThemes` | | Install all pending theme updates on Dashboard -> Updates|
|
| `updateThemes` | | Install all pending theme updates on Dashboard -> Updates|
|
||||||
|
| `verifyCannotDownloadFromBecause` | `page, reason` | Verify that cannot download a product from `page` because of `reason` |
|
||||||
|
| `verifyDownloadableProductPermission` | `productName, expirationDate, downloadsRemaining` | Verify the attributes of a downloadable product permission in order |
|
||||||
| `runDatabaseUpdate` || Runs the database update if needed |
|
| `runDatabaseUpdate` || Runs the database update if needed |
|
||||||
|
| `openDownloadLink` | | Open the download link of a product |
|
||||||
|
|
||||||
### Shopper `shopper`
|
### Shopper `shopper`
|
||||||
|
|
||||||
|
@ -160,6 +166,8 @@ Please note: if you're using a non-SSL environment (such as a Docker container f
|
||||||
| `deleteAllShippingZones` | `testResponse` | Permanently delete all shipping zones except the default |
|
| `deleteAllShippingZones` | `testResponse` | Permanently delete all shipping zones except the default |
|
||||||
| `deleteCoupon` | `couponId` | Permanently delete a coupon |
|
| `deleteCoupon` | `couponId` | Permanently delete a coupon |
|
||||||
| `deleteCustomerByEmail` | `emailAddress` | Delete customer user account. Posts are reassigned to user ID 1 |
|
| `deleteCustomerByEmail` | `emailAddress` | Delete customer user account. Posts are reassigned to user ID 1 |
|
||||||
|
| `deleteOrder` | `orderId` | Permanently delete an order |
|
||||||
|
| `deleteProduct` | `productId` | Permanently delete a simple product |
|
||||||
| `getSystemEnvironment` | | Get the current environment from the WooCommerce system status API. |
|
| `getSystemEnvironment` | | Get the current environment from the WooCommerce system status API. |
|
||||||
| `resetOnboarding` | | Reset onboarding settings |
|
| `resetOnboarding` | | Reset onboarding settings |
|
||||||
| `resetSettingsGroupToDefault` | `settingsGroup`, `testResponse` | Reset settings in settings group to default except `select` fields |
|
| `resetSettingsGroupToDefault` | `settingsGroup`, `testResponse` | Reset settings in settings group to default except `select` fields |
|
||||||
|
@ -203,13 +211,16 @@ There is a general utilities object `utils` with the following functions:
|
||||||
| `completeOnboardingWizard` | | completes the onboarding wizard with some default settings |
|
| `completeOnboardingWizard` | | completes the onboarding wizard with some default settings |
|
||||||
| `createCoupon` | `couponAmount`, `couponType` | creates a basic coupon. Default amount is 5. Default coupon type is fixed discount. Returns the generated coupon code. |
|
| `createCoupon` | `couponAmount`, `couponType` | creates a basic coupon. Default amount is 5. Default coupon type is fixed discount. Returns the generated coupon code. |
|
||||||
| `createGroupedProduct` | | creates a grouped product for the grouped product tests. Returns the product id. |
|
| `createGroupedProduct` | | creates a grouped product for the grouped product tests. Returns the product id. |
|
||||||
|
| `createSimpleDownloadableProduct` | `name, downloadLimit, downloadName, price` | Create a simple downloadable product |
|
||||||
| `createSimpleOrder` | `status` | creates a basic order with the provided status string |
|
| `createSimpleOrder` | `status` | creates a basic order with the provided status string |
|
||||||
| `createSimpleProduct` | | creates the simple product configured in default.json. Returns the product id. |
|
| `createSimpleProduct` | | creates the simple product configured in default.json. Returns the product id. |
|
||||||
| `createSimpleProductWithCategory` | `name`, `price`,`categoryName` | creates a simple product used passed values. Returns the product id. |
|
| `createSimpleProductWithCategory` | `name`, `price`,`categoryName` | creates a simple product used passed values. Returns the product id. |
|
||||||
| `createVariableProduct` | | creates a variable product for the variable product tests. Returns the product id. |
|
| `createVariableProduct` | | creates a variable product for the variable product tests. Returns the product id. |
|
||||||
| `deleteAllEmailLogs` | | deletes the emails generated by WP Mail Logging plugin |
|
| `deleteAllEmailLogs` | | deletes the emails generated by WP Mail Logging plugin |
|
||||||
| `evalAndClick` | `selector` | helper method that clicks an element inserted in the DOM by a script |
|
| `evalAndClick` | `selector` | helper method that clicks an element inserted in the DOM by a script |
|
||||||
|
| `getSelectorAttribute` | `selector, attribute` | Retrieve the desired HTML attribute from a selector |
|
||||||
| `moveAllItemsToTrash` | | helper method that checks every item in a list page and moves them to the trash |
|
| `moveAllItemsToTrash` | | helper method that checks every item in a list page and moves them to the trash |
|
||||||
|
| `orderPageSaveChanges` | | Save the current order page |
|
||||||
| `permalinkSettingsPageSaveChanges` | | Save the current Permalink settings |
|
| `permalinkSettingsPageSaveChanges` | | Save the current Permalink settings |
|
||||||
| `removeCoupon` | | helper method that removes a single coupon within cart or checkout |
|
| `removeCoupon` | | helper method that removes a single coupon within cart or checkout |
|
||||||
| `selectOptionInSelect2` | `selector, value` | helper method that searchs for select2 type fields and select plus insert value inside |
|
| `selectOptionInSelect2` | `selector, value` | helper method that searchs for select2 type fields and select plus insert value inside |
|
||||||
|
@ -222,6 +233,7 @@ There is a general utilities object `utils` with the following functions:
|
||||||
| `verifyCheckboxIsSet` | `selector` | Verify that a checkbox is checked |
|
| `verifyCheckboxIsSet` | `selector` | Verify that a checkbox is checked |
|
||||||
| `verifyCheckboxIsUnset` | `selector` | Verify that a checkbox is unchecked |
|
| `verifyCheckboxIsUnset` | `selector` | Verify that a checkbox is unchecked |
|
||||||
| `verifyPublishAndTrash` | `button, publishNotice, publishVerification, trashVerification` | Verify that an item can be published and trashed |
|
| `verifyPublishAndTrash` | `button, publishNotice, publishVerification, trashVerification` | Verify that an item can be published and trashed |
|
||||||
|
| `verifyValueOfElementAttribute` | `selector, attribute, expectedValue` | Assert the value of the desired HTML attribute of a selector |
|
||||||
| `verifyValueOfInputField` | `selector, value` | Verify an input contains the passed value |
|
| `verifyValueOfInputField` | `selector, value` | Verify an input contains the passed value |
|
||||||
| `clickFilter` | `selector` | Click on a list page filter |
|
| `clickFilter` | `selector` | Click on a list page filter |
|
||||||
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
|
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
|
||||||
|
|
|
@ -27,6 +27,8 @@ const simpleProductPrice = config.has('products.simple.price') ? config.get('pro
|
||||||
const defaultVariableProduct = config.get('products.variable');
|
const defaultVariableProduct = config.get('products.variable');
|
||||||
const defaultGroupedProduct = config.get('products.grouped');
|
const defaultGroupedProduct = config.get('products.grouped');
|
||||||
|
|
||||||
|
const uuid = require( 'uuid' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify and publish
|
* Verify and publish
|
||||||
*
|
*
|
||||||
|
@ -233,6 +235,28 @@ const createSimpleProductWithCategory = async ( productName, productPrice, categ
|
||||||
return product.id;
|
return product.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create simple downloadable product
|
||||||
|
*
|
||||||
|
* @param name Product's name. Defaults to 'Simple Product' (see createSimpleProduct definition).
|
||||||
|
* @param downloadLimit Product's download limit. Defaults to '-1' (unlimited).
|
||||||
|
* @param downloadName Product's download name. Defaults to 'Single'.
|
||||||
|
* @param price Product's price. Defaults to '$9.99' (see createSimpleProduct definition).
|
||||||
|
*/
|
||||||
|
const createSimpleDownloadableProduct = async ( name, downloadLimit = -1, downloadName = 'Single', price ) => {
|
||||||
|
const productDownloadDetails = {
|
||||||
|
downloadable: true,
|
||||||
|
downloads: [ {
|
||||||
|
id: uuid.v4(),
|
||||||
|
name: downloadName,
|
||||||
|
file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg'
|
||||||
|
} ],
|
||||||
|
download_limit: downloadLimit
|
||||||
|
};
|
||||||
|
|
||||||
|
return await createSimpleProduct( name, price, productDownloadDetails );
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create variable product.
|
* Create variable product.
|
||||||
* Also, create variations for all attributes.
|
* Also, create variations for all attributes.
|
||||||
|
@ -594,6 +618,7 @@ export {
|
||||||
createCoupon,
|
createCoupon,
|
||||||
addShippingZoneAndMethod,
|
addShippingZoneAndMethod,
|
||||||
createSimpleProductWithCategory,
|
createSimpleProductWithCategory,
|
||||||
|
createSimpleDownloadableProduct,
|
||||||
clickUpdateOrder,
|
clickUpdateOrder,
|
||||||
deleteAllEmailLogs,
|
deleteAllEmailLogs,
|
||||||
deleteAllShippingZones,
|
deleteAllShippingZones,
|
||||||
|
|
|
@ -6,7 +6,16 @@ const config = require( 'config' );
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
const { clearAndFillInput, setCheckbox } = require( '../page-utils' );
|
const {
|
||||||
|
clearAndFillInput,
|
||||||
|
selectOptionInSelect2,
|
||||||
|
setCheckbox,
|
||||||
|
verifyValueOfInputField,
|
||||||
|
getSelectorAttribute,
|
||||||
|
orderPageSaveChanges,
|
||||||
|
verifyValueOfElementAttribute,
|
||||||
|
} = require( '../page-utils' );
|
||||||
|
|
||||||
const {
|
const {
|
||||||
WP_ADMIN_ALL_ORDERS_VIEW,
|
WP_ADMIN_ALL_ORDERS_VIEW,
|
||||||
WP_ADMIN_ALL_PRODUCTS_VIEW,
|
WP_ADMIN_ALL_PRODUCTS_VIEW,
|
||||||
|
@ -36,6 +45,12 @@ const { getSlug, waitForTimeout } = require('./utils');
|
||||||
const baseUrl = config.get( 'url' );
|
const baseUrl = config.get( 'url' );
|
||||||
const WP_ADMIN_SINGLE_CPT_VIEW = ( postId ) => baseUrl + `wp-admin/post.php?post=${ postId }&action=edit`;
|
const WP_ADMIN_SINGLE_CPT_VIEW = ( postId ) => baseUrl + `wp-admin/post.php?post=${ postId }&action=edit`;
|
||||||
|
|
||||||
|
// Reusable selectors
|
||||||
|
const INPUT_DOWNLOADS_REMAINING = 'input[name="downloads_remaining[0]"]';
|
||||||
|
const INPUT_EXPIRATION_DATE = 'input[name="access_expires[0]"]';
|
||||||
|
const ORDER_DOWNLOADS = '#woocommerce-order-downloads';
|
||||||
|
const BTN_COPY_DOWNLOAD_LINK = '#copy-download-link';
|
||||||
|
|
||||||
const merchant = {
|
const merchant = {
|
||||||
login: async () => {
|
login: async () => {
|
||||||
await page.goto( WP_ADMIN_LOGIN, {
|
await page.goto( WP_ADMIN_LOGIN, {
|
||||||
|
@ -149,7 +164,6 @@ const merchant = {
|
||||||
} );
|
} );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
goToOrder: async ( orderId ) => {
|
goToOrder: async ( orderId ) => {
|
||||||
await page.goto( WP_ADMIN_SINGLE_CPT_VIEW( orderId ), {
|
await page.goto( WP_ADMIN_SINGLE_CPT_VIEW( orderId ), {
|
||||||
waitUntil: 'networkidle0',
|
waitUntil: 'networkidle0',
|
||||||
|
@ -198,6 +212,91 @@ const merchant = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addDownloadableProductPermission: async ( productName ) => {
|
||||||
|
// Add downloadable product permission
|
||||||
|
await selectOptionInSelect2( productName );
|
||||||
|
await expect( page ).toClick( 'button.grant_access' );
|
||||||
|
|
||||||
|
// Save the order changes
|
||||||
|
await orderPageSaveChanges();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDownloadableProductPermission: async ( productName, expirationDate, downloadsRemaining ) => {
|
||||||
|
// Update downloadable product permission
|
||||||
|
await expect(page).toClick( ORDER_DOWNLOADS, { text: productName } );
|
||||||
|
|
||||||
|
if ( downloadsRemaining ) {
|
||||||
|
await clearAndFillInput( INPUT_DOWNLOADS_REMAINING, downloadsRemaining );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( expirationDate ) {
|
||||||
|
await clearAndFillInput( INPUT_EXPIRATION_DATE, expirationDate );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the order changes
|
||||||
|
await orderPageSaveChanges();
|
||||||
|
},
|
||||||
|
|
||||||
|
revokeDownloadableProductPermission: async ( productName ) => {
|
||||||
|
// Revoke downloadable product permission
|
||||||
|
const permission = await expect(page).toMatchElement( 'div.wc-metabox > h3', { text: productName } );
|
||||||
|
await expect( permission ).toClick('button.revoke_access');
|
||||||
|
|
||||||
|
// Wait for auto save
|
||||||
|
await waitForTimeout( 2000 );
|
||||||
|
|
||||||
|
// Save the order changes
|
||||||
|
await orderPageSaveChanges();
|
||||||
|
},
|
||||||
|
|
||||||
|
verifyDownloadableProductPermission: async ( productName, expirationDate = '', downloadsRemaining = '' ) => {
|
||||||
|
// Open downloadable product permission details
|
||||||
|
await expect(page).toClick( ORDER_DOWNLOADS, { text: productName } );
|
||||||
|
|
||||||
|
// Verify downloads remaining
|
||||||
|
await verifyValueOfElementAttribute( INPUT_DOWNLOADS_REMAINING, 'placeholder', 'Unlimited' );
|
||||||
|
await verifyValueOfInputField( INPUT_DOWNLOADS_REMAINING, downloadsRemaining );
|
||||||
|
|
||||||
|
// Verify downloads expiration date
|
||||||
|
await verifyValueOfElementAttribute( INPUT_EXPIRATION_DATE, 'placeholder', 'Never' );
|
||||||
|
await verifyValueOfInputField( INPUT_EXPIRATION_DATE, expirationDate );
|
||||||
|
|
||||||
|
// Verify 'Copy link' and 'View report' buttons are available
|
||||||
|
await expect( page ).toMatchElement( BTN_COPY_DOWNLOAD_LINK, { text: 'Copy link'} );
|
||||||
|
await expect( page ).toMatchElement( '.button', { text: 'View report' } );
|
||||||
|
},
|
||||||
|
|
||||||
|
openDownloadLink: async () => {
|
||||||
|
// Open downloadable product permission details
|
||||||
|
await expect( page ).toClick( '#woocommerce-order-downloads > div.inside > div > div.wc-metaboxes > div' );
|
||||||
|
|
||||||
|
// Get download link
|
||||||
|
const downloadLink = await getSelectorAttribute( BTN_COPY_DOWNLOAD_LINK, 'href' );
|
||||||
|
|
||||||
|
const newPage = await browser.newPage();
|
||||||
|
|
||||||
|
// Open download link in new tab
|
||||||
|
await newPage.goto( downloadLink , {
|
||||||
|
waitUntil: 'networkidle0',
|
||||||
|
} );
|
||||||
|
|
||||||
|
return newPage;
|
||||||
|
},
|
||||||
|
|
||||||
|
verifyCannotDownloadFromBecause: async ( page, reason ) => {
|
||||||
|
// Select download page tab
|
||||||
|
await page.bringToFront();
|
||||||
|
|
||||||
|
// Verify error in download page
|
||||||
|
await expect( page.title() ).resolves.toMatch( 'WordPress › Error' );
|
||||||
|
await expect( page ).toMatchElement( 'div.wp-die-message', {
|
||||||
|
text: reason
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Close tab
|
||||||
|
await page.close();
|
||||||
|
},
|
||||||
|
|
||||||
openNewShipping: async () => {
|
openNewShipping: async () => {
|
||||||
await page.goto( WP_ADMIN_NEW_SHIPPING_ZONE, {
|
await page.goto( WP_ADMIN_NEW_SHIPPING_ZONE, {
|
||||||
waitUntil: 'networkidle0',
|
waitUntil: 'networkidle0',
|
||||||
|
|
|
@ -108,6 +108,16 @@ export const withRestApi = {
|
||||||
const repository = SimpleProduct.restRepository( client );
|
const repository = SimpleProduct.restRepository( client );
|
||||||
await deleteAllRepositoryObjects( repository );
|
await deleteAllRepositoryObjects( repository );
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Use api package to delete a product.
|
||||||
|
*
|
||||||
|
* @param {number} productId Product ID.
|
||||||
|
* @return {Promise} Promise resolving once the product has been deleted.
|
||||||
|
*/
|
||||||
|
deleteProduct: async ( productId ) => {
|
||||||
|
const repository = SimpleProduct.restRepository( client );
|
||||||
|
await repository.delete( productId );
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Use the API to delete all product attributes.
|
* Use the API to delete all product attributes.
|
||||||
*
|
*
|
||||||
|
@ -177,6 +187,16 @@ export const withRestApi = {
|
||||||
const repository = Order.restRepository( client );
|
const repository = Order.restRepository( client );
|
||||||
await deleteAllRepositoryObjects( repository, null, orderStatuses );
|
await deleteAllRepositoryObjects( repository, null, orderStatuses );
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Use api package to delete an order.
|
||||||
|
*
|
||||||
|
* @param {number} orderId Order ID.
|
||||||
|
* @return {Promise} Promise resolving once the order has been deleted.
|
||||||
|
*/
|
||||||
|
deleteOrder: async ( orderId ) => {
|
||||||
|
const repository = Order.restRepository( client );
|
||||||
|
await repository.delete( orderId );
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Adds a shipping zone along with a shipping method using the API.
|
* Adds a shipping zone along with a shipping method using the API.
|
||||||
*
|
*
|
||||||
|
|
|
@ -53,6 +53,14 @@ export const permalinkSettingsPageSaveChanges = async () => {
|
||||||
] );
|
] );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save changes on Order page.
|
||||||
|
*/
|
||||||
|
export const orderPageSaveChanges = async () => {
|
||||||
|
await expect( page ).toClick( 'button.save_order' );
|
||||||
|
await page.waitForSelector( '#message' );
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set checkbox.
|
* Set checkbox.
|
||||||
*
|
*
|
||||||
|
@ -335,3 +343,25 @@ export async function waitForSelector( page, selector, options = {} ) {
|
||||||
const element = await page.waitForSelector( selector, options );
|
const element = await page.waitForSelector( selector, options );
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the desired HTML attribute from a selector.
|
||||||
|
* For example, the 'value' attribute of an input element.
|
||||||
|
* @param {string} selector Selector of the element you want to get the attribute from.
|
||||||
|
* @param {string} attribute The desired HTML attribute.
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
export async function getSelectorAttribute ( selector, attribute ) {
|
||||||
|
return await page.$eval( selector, ( element, attribute ) => element.getAttribute( attribute ), attribute );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts the value of the desired HTML attribute of a selector.
|
||||||
|
* @param {string} selector Selector of the element you want to verify.
|
||||||
|
* @param {string} attribute The desired HTML attribute.
|
||||||
|
* @param {string} expectedValue The expected value.
|
||||||
|
*/
|
||||||
|
export async function verifyValueOfElementAttribute ( selector, attribute, expectedValue ) {
|
||||||
|
const actualValue = await getSelectorAttribute ( selector, attribute );
|
||||||
|
expect( actualValue ).toBe( expectedValue );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue