diff options
16 files changed, 226 insertions, 78 deletions
diff --git a/addons/point_of_sale/static/tests/tours/Chrome.tour.js b/addons/point_of_sale/static/tests/tours/Chrome.tour.js index 55c9e6a309d..f00af8fddd7 100644 --- a/addons/point_of_sale/static/tests/tours/Chrome.tour.js +++ b/addons/point_of_sale/static/tests/tours/Chrome.tour.js @@ -13,13 +13,13 @@ odoo.define('point_of_sale.tour.Chrome', function (require) { // Order 1 is at Product Screen ProductScreen.do.clickHomeCategory(); - ProductScreen.exec.addOrderline('Desk Pad', '1', '2'); + ProductScreen.exec.addOrderline('Desk Pad', '1', '2', '2.0'); Chrome.do.clickTicketButton(); TicketScreen.check.checkStatus('-0001', 'Ongoing'); // Order 2 is at Payment Screen TicketScreen.do.clickNewTicket(); - ProductScreen.exec.addOrderline('Monitor Stand', '3', '4'); + ProductScreen.exec.addOrderline('Monitor Stand', '3', '4', '12.0'); ProductScreen.do.clickPayButton(); PaymentScreen.check.isShown(); Chrome.do.clickTicketButton(); @@ -27,9 +27,11 @@ odoo.define('point_of_sale.tour.Chrome', function (require) { // Order 3 is at Receipt Screen TicketScreen.do.clickNewTicket(); - ProductScreen.exec.addOrderline('Whiteboard Pen', '5', '6'); + ProductScreen.exec.addOrderline('Whiteboard Pen', '5', '6', '30.0'); ProductScreen.do.clickPayButton(); PaymentScreen.do.clickPaymentMethod('Bank'); + PaymentScreen.check.remainingIs('0.0'); + PaymentScreen.check.validateButtonIsHighlighted(true); PaymentScreen.do.clickValidate(); ReceiptScreen.check.isShown(); Chrome.do.clickTicketButton(); @@ -57,6 +59,8 @@ odoo.define('point_of_sale.tour.Chrome', function (require) { ProductScreen.do.clickPayButton(); PaymentScreen.do.clickPaymentMethod('Cash'); PaymentScreen.do.pressNumpad('2 0'); + PaymentScreen.check.remainingIs('0.0'); + PaymentScreen.check.validateButtonIsHighlighted(true); PaymentScreen.do.clickValidate(); ReceiptScreen.check.totalAmountContains('2.0'); diff --git a/addons/point_of_sale/static/tests/tours/PaymentScreen.tour.js b/addons/point_of_sale/static/tests/tours/PaymentScreen.tour.js index 5626395ba63..cba1a4fa3e9 100644 --- a/addons/point_of_sale/static/tests/tours/PaymentScreen.tour.js +++ b/addons/point_of_sale/static/tests/tours/PaymentScreen.tour.js @@ -9,6 +9,7 @@ odoo.define('point_of_sale.tour.PaymentScreen', function (require) { startSteps(); ProductScreen.exec.addOrderline('Letter Tray', '10'); + ProductScreen.check.selectedOrderlineHas('Letter Tray', '10.0'); ProductScreen.do.clickPayButton(); PaymentScreen.check.emptyPaymentlines('52.8'); @@ -19,7 +20,9 @@ odoo.define('point_of_sale.tour.PaymentScreen', function (require) { PaymentScreen.check.changeIs('0.0'); PaymentScreen.check.validateButtonIsHighlighted(false); // remove the selected paymentline with multiple backspace presses - PaymentScreen.do.pressNumpad('Backspace Backspace Backspace'); + PaymentScreen.do.pressNumpad('Backspace Backspace'); + PaymentScreen.check.selectedPaymentlineHas('Cash', '0.00'); + PaymentScreen.do.pressNumpad('Backspace'); PaymentScreen.check.emptyPaymentlines('52.8'); // Pay with bank, the selected line should have full amount diff --git a/addons/point_of_sale/static/tests/tours/ProductScreen.tour.js b/addons/point_of_sale/static/tests/tours/ProductScreen.tour.js index d2a253de924..ae2b9261c5e 100644 --- a/addons/point_of_sale/static/tests/tours/ProductScreen.tour.js +++ b/addons/point_of_sale/static/tests/tours/ProductScreen.tour.js @@ -27,6 +27,7 @@ odoo.define('point_of_sale.tour.ProductScreen', function (require) { // Check effects of clicking numpad buttons ProductScreen.do.clickOrderline('Letter Tray', '1'); + ProductScreen.check.selectedOrderlineHas('Letter Tray', '1.0'); ProductScreen.do.pressNumpad('Backspace'); ProductScreen.check.selectedOrderlineHas('Letter Tray', '0.0', '0.0'); ProductScreen.do.pressNumpad('Backspace'); @@ -46,10 +47,10 @@ odoo.define('point_of_sale.tour.ProductScreen', function (require) { ProductScreen.do.pressNumpad('Price'); ProductScreen.do.pressNumpad('1'); ProductScreen.check.selectedOrderlineHas('Desk Organizer', '123.5', '123.5'); - ProductScreen.do.pressNumpad('1 . 0'); + ProductScreen.do.pressNumpad('1 .'); ProductScreen.check.selectedOrderlineHas('Desk Organizer', '123.5', '1,358.5'); ProductScreen.do.pressNumpad('Disc'); - ProductScreen.do.pressNumpad('5 . 0'); + ProductScreen.do.pressNumpad('5 .'); ProductScreen.check.selectedOrderlineHas('Desk Organizer', '123.5', '1,290.58'); ProductScreen.do.pressNumpad('Qty'); ProductScreen.do.pressNumpad('Backspace'); @@ -76,22 +77,29 @@ odoo.define('point_of_sale.tour.ProductScreen', function (require) { ProductScreen.do.clickOrderline('Whiteboard Pen', '1.0'); ProductScreen.check.selectedOrderlineHas('Whiteboard Pen', '1.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Whiteboard Pen', '0.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Monitor Stand', '1.0'); ProductScreen.do.clickOrderline('Wall Shelf Unit', '1.0'); ProductScreen.check.selectedOrderlineHas('Wall Shelf Unit', '1.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Wall Shelf Unit', '0.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Monitor Stand', '1.0'); ProductScreen.do.clickOrderline('Small Shelf', '1.0'); ProductScreen.check.selectedOrderlineHas('Small Shelf', '1.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Small Shelf', '0.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Monitor Stand', '1.0'); ProductScreen.do.clickOrderline('Magnetic Board', '1.0'); ProductScreen.check.selectedOrderlineHas('Magnetic Board', '1.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Magnetic Board', '0.0'); ProductScreen.do.pressNumpad('Backspace'); - // Monitor Stand should be automatically selected at this point ProductScreen.check.selectedOrderlineHas('Monitor Stand', '1.0'); ProductScreen.do.pressNumpad('Backspace'); + ProductScreen.check.selectedOrderlineHas('Monitor Stand', '0.0'); ProductScreen.do.pressNumpad('Backspace'); ProductScreen.check.orderIsEmpty(); diff --git a/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js b/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js index 1fc98063383..d15f24b5089 100644 --- a/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js +++ b/addons/point_of_sale/static/tests/tours/ReceiptScreen.tour.js @@ -11,9 +11,11 @@ odoo.define('point_of_sale.tour.ReceiptScreen', function (require) { startSteps(); // press close button in receipt screen - ProductScreen.exec.addOrderline('Letter Tray', '10', '5.0'); + ProductScreen.exec.addOrderline('Letter Tray', '10', '5'); + ProductScreen.check.selectedOrderlineHas('Letter Tray', '10'); ProductScreen.do.clickPayButton(); PaymentScreen.do.clickPaymentMethod('Bank'); + PaymentScreen.check.validateButtonIsHighlighted(true); PaymentScreen.do.clickValidate(); ReceiptScreen.check.receiptIsThere(); // letter tray has 10% tax (search SRC) @@ -22,15 +24,19 @@ odoo.define('point_of_sale.tour.ReceiptScreen', function (require) { // send email in receipt screen ProductScreen.do.clickHomeCategory(); - ProductScreen.exec.addOrderline('Desk Pad', '6', '5.0'); - ProductScreen.exec.addOrderline('Whiteboard Pen', '6', '6.1'); - ProductScreen.exec.addOrderline('Monitor Stand', '6', '1.3'); + ProductScreen.exec.addOrderline('Desk Pad', '6', '5', '30.0'); + ProductScreen.exec.addOrderline('Whiteboard Pen', '6', '6', '36.0'); + ProductScreen.exec.addOrderline('Monitor Stand', '6', '1', '6.0'); ProductScreen.do.clickPayButton(); PaymentScreen.do.clickPaymentMethod('Cash'); - PaymentScreen.do.pressNumpad('8 0 0'); + PaymentScreen.do.pressNumpad('7 0'); + PaymentScreen.check.remainingIs('2.0'); + PaymentScreen.do.pressNumpad('0'); + PaymentScreen.check.remainingIs('0.00'); + PaymentScreen.check.changeIs('628.0'); PaymentScreen.do.clickValidate(); ReceiptScreen.check.receiptIsThere(); - ReceiptScreen.check.totalAmountContains('74.4'); + ReceiptScreen.check.totalAmountContains('72.0'); ReceiptScreen.do.setEmail('test@receiptscreen.com'); ReceiptScreen.do.clickSend(); ReceiptScreen.check.emailIsSuccessful(); @@ -38,7 +44,7 @@ odoo.define('point_of_sale.tour.ReceiptScreen', function (require) { // order with tip // check if tip amount is displayed - ProductScreen.exec.addOrderline('Desk Pad', '6', '5.0'); + ProductScreen.exec.addOrderline('Desk Pad', '6', '5'); ProductScreen.do.clickPayButton(); PaymentScreen.do.clickTipButton(); NumberPopup.do.pressNumpad('1'); diff --git a/addons/point_of_sale/static/tests/tours/helpers/NumberPopupTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/NumberPopupTourMethods.js index 44fe6890c9e..c12d0d02edd 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/NumberPopupTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/NumberPopupTourMethods.js @@ -5,6 +5,9 @@ odoo.define('point_of_sale.tour.NumberPopupTourMethods', function (require) { class Do { /** + * Note: Maximum of 2 characters because NumberBuffer only allows 2 consecutive + * fast inputs. Fast inputs is the case in tours. + * * @param {String} keys space-separated input keys */ pressNumpad(keys) { diff --git a/addons/point_of_sale/static/tests/tours/helpers/PaymentScreenTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/PaymentScreenTourMethods.js index c4862c0ba46..93a5cef6aa7 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/PaymentScreenTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/PaymentScreenTourMethods.js @@ -59,6 +59,9 @@ odoo.define('point_of_sale.tour.PaymentScreenTourMethods', function (require) { /** * Press the numpad in sequence based on the given space-separated keys. + * Note: Maximum of 2 characters because NumberBuffer only allows 2 consecutive + * fast inputs. Fast inputs is the case in tours. + * * @param {String} keys space-separated numpad keys */ pressNumpad(keys) { diff --git a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js index dab5ae15683..464f8c1c043 100644 --- a/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js +++ b/addons/point_of_sale/static/tests/tours/helpers/ProductScreenTourMethods.js @@ -52,6 +52,9 @@ odoo.define('point_of_sale.tour.ProductScreenTourMethods', function (require) { /** * Press the numpad in sequence based on the given space-separated keys. + * NOTE: Maximum of 2 characters because NumberBuffer only allows 2 consecutive + * fast inputs. Fast inputs is the case in tours. + * * @param {String} keys space-separated numpad keys */ pressNumpad(keys) { @@ -187,18 +190,43 @@ odoo.define('point_of_sale.tour.ProductScreenTourMethods', function (require) { content: `order total amount is '${amount}'`, trigger: `.order-container .order .summary .value:contains("${amount}")`, run: () => {}, + } + ] + } + modeIsActive(mode) { + return [ + { + content: `'${mode}' is active`, + trigger: `.numpad button.selected-mode:contains('${mode}')`, + run: function () {}, }, ]; } } class Execute { - addOrderline(productName, quantity, price) { + /** + * Create an orderline for the given `productName` and `quantity`. + * - If `unitPrice` is provided, price of the product of the created line + * is changed to that value. + * - If `expectedTotal` is provided, the created orderline (which is the currently + * selected orderline) is checked if it contains the correct quantity and total + * price. + * + * @param {string} productName + * @param {string} quantity + * @param {string} unitPrice + * @param {string} expectedTotal + */ + addOrderline(productName, quantity, unitPrice = undefined, expectedTotal = undefined) { const res = this._do.clickDisplayedProduct(productName); - if (price) { + if (unitPrice) { res.push(...this._do.pressNumpad('Price')); - res.push(...this._do.pressNumpad(price.toString().split('').join(' '))); + res.push(...this._check.modeIsActive('Price')); + res.push(...this._do.pressNumpad(unitPrice.toString().split('').join(' '))); + res.push(...this._check.selectedOrderlineHas(productName, '1.0', unitPrice)); res.push(...this._do.pressNumpad('Qty')); + res.push(...this._check.modeIsActive('Qty')); } for (let char of quantity.toString()) { if ('.0123456789'.includes(char)) { @@ -207,6 +235,11 @@ odoo.define('point_of_sale.tour.ProductScreenTourMethods', function (require) { res.push(...this._do.pressNumpad('+/-')); } } + if (expectedTotal) { + res.push(...this._check.selectedOrderlineHas(productName, quantity, expectedTotal)); + } else { + res.push(...this._check.selectedOrderlineHas(productName, quantity)); + } return res; } addMultiOrderlines(...list) { diff --git a/addons/point_of_sale/static/tests/tours/point_of_sale.js b/addons/point_of_sale/static/tests/tours/point_of_sale.js index 4e5584ffcd9..28312bcd64e 100644 --- a/addons/point_of_sale/static/tests/tours/point_of_sale.js +++ b/addons/point_of_sale/static/tests/tours/point_of_sale.js @@ -152,29 +152,51 @@ odoo.define('point_of_sale.tour.pricelist', function (require) { content: "change qty to 2 kg", trigger: ".numpad button.input-button:visible:contains('2')", }, { + content: "qty of Wall Shelf line should be 2", + trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Wall Shelf')", + extra_trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Wall Shelf') ~ .info-list .info em:contains('2.0')", + run: function() {}, + }, { content: "verify that unit price of shelf changed to $1", trigger: ".total > .value:contains('$ 2.00')", + run: function() {}, }, { content: "order different shelf", trigger: ".product:contains('Small Shelf')", }, { + content: "Small Shelf line should be selected with quantity 1", + trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Small Shelf')", + extra_trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Small Shelf') ~ .info-list .info em:contains('1.0')", + run: function() {} + }, { content: "change to price mode", trigger: ".numpad button:contains('Price')", }, { + content: "make sure price mode is activated", + trigger: ".numpad button.selected-mode:contains('Price')", + run: function() {}, + }, { content: "manually override the unit price of these shelf to $5", trigger: ".numpad button.input-button:visible:contains('5')", }, { + content: "Small Shelf line should be selected with unit price of 5", + trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Small Shelf')", + extra_trigger: ".order-container .orderlines .orderline.selected .product-name:contains('Small Shelf') ~ .price:contains('5.0')", + }, { content: "change back to qty mode", trigger: ".numpad button:contains('Qty')", }, { + content: "make sure qty mode is activated", + trigger: ".numpad button.selected-mode:contains('Qty')", + run: function() {}, + }, { content: "click pricelist button", trigger: ".control-button.o_pricelist_button", }, { content: "select public pricelist", trigger: ".selection-item:contains('Public Pricelist')", }, { - content: "verify that the boni shelf have been recomputed and the\ -shelf have not (their price was manually overridden)", + content: "verify that the boni shelf have been recomputed and the shelf have not (their price was manually overridden)", trigger: ".total > .value:contains('$ 8.96')", }, { content: "click pricelist button", @@ -206,7 +228,7 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { }, { content: 'the ' + product_name + ' have been added to the order', trigger: '.order .product-name:contains("' + product_name + '")', - run: function () {}, // it's a check + run: function () {}, }]; } @@ -220,7 +242,7 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { }, { content: 'the fiscal position ' + fp_name + ' has been set to the order', trigger: '.control-button.o_fiscal_position_button:contains("' + fp_name + '")', - run: function () {}, // it's a check + run: function () {}, }]; } @@ -233,20 +255,49 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { trigger: keypad_selector + ' .input-button:contains("' + current_char + '"):visible' }); } - steps.push({ - content: 'do nothing check', - trigger: '.pos', - run: function () {}, - }) return steps; } - function generate_payment_screen_keypad_steps(amount_str) { - return generate_keypad_steps(amount_str, '.payment-numpad'); + function press_payment_numpad(val) { + return [{ + content: `press ${val} on payment screen numpad`, + trigger: `.payment-numpad .input-button:contains("${val}"):visible`, + }] + } + + function press_product_numpad(val) { + return [{ + content: `press ${val} on product screen numpad`, + trigger: `.numpad .input-button:contains("${val}"):visible`, + }] } - function generate_product_screen_keypad_steps(amount_str) { - return generate_keypad_steps(amount_str, '.numpad'); + function selected_payment_has(name, val) { + return [{ + content: `selected payment is ${name} and has ${val}`, + trigger: `.paymentlines .paymentline.selected .payment-name:contains("${name}")`, + extra_trigger: `.paymentlines .paymentline.selected .payment-name:contains("${name}") ~ .payment-amount:contains("${val}")`, + run: function () {}, + }] + } + + function selected_orderline_has({ product, price = null, quantity = null }) { + const result = []; + if (price !== null) { + result.push({ + content: `Selected line has product '${product}' and price '${price}'`, + trigger: `.order-container .orderlines .orderline.selected .product-name:contains("${product}") ~ span.price:contains("${price}")`, + run: function () {}, + }); + } + if (quantity !== null) { + result.push({ + content: `Selected line has product '${product}' and quantity '${quantity}'`, + trigger: `.order-container .orderlines .orderline.selected .product-name:contains('${product}') ~ .info-list .info em:contains('${quantity}')`, + run: function () {}, + }); + } + return result; } function verify_order_total(total_str) { @@ -274,7 +325,7 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { }, { content: "verify that the order has been successfully sent to the backend", trigger: ".js_connected:visible", - run: function () {}, // it's a check + run: function () {}, }, { content: "click Next Order", trigger: '.receipt-screen .button.next.highlight:visible', @@ -288,11 +339,10 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { var steps = [{ content: 'waiting for loading to finish', trigger: 'body:not(:has(.loader))', - run: function () {}, // it's a check + run: function () {}, }, { // Leave category displayed by default content: "click category switch", trigger: ".breadcrumb-home", - run: 'click', }]; steps = steps.concat(add_product_to_order('Desk Organizer')); @@ -310,15 +360,16 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { remaining := 0.00 change := 1.50 */ - steps = steps.concat(generate_payment_screen_keypad_steps("5.20")); + steps = steps.concat(press_payment_numpad('5')); + steps = steps.concat(selected_payment_has('Cash', '5.0')); steps = steps.concat([{ content: "verify remaining", - trigger: '.payment-status-remaining .amount:contains("5.00")', - run: function () {}, // it's a check + trigger: '.payment-status-remaining .amount:contains("5.20")', + run: function () {}, }, { content: "verify change", trigger: '.payment-status-change .amount:contains("0.00")', - run: function () {}, // it's a check + run: function () {}, }]); /* make additional payment line of 6.50 @@ -333,30 +384,39 @@ odoo.define('point_of_sale.tour.acceptance', function (require) { content: "pay with cash", trigger: '.paymentmethod:contains("Cash")', }]); - steps = steps.concat(generate_payment_screen_keypad_steps("6.50")); - + steps = steps.concat(selected_payment_has('Cash', '5.2')); + steps = steps.concat(press_payment_numpad('6')) + steps = steps.concat(selected_payment_has('Cash', '6.0')); steps = steps.concat([{ content: "verify remaining", trigger: '.payment-status-remaining .amount:contains("0.00")', - run: function () {}, // it's a check + run: function () {}, }, { content: "verify change", - trigger: '.payment-status-change .amount:contains("1.50")', - run: function () {}, // it's a check + trigger: '.payment-status-change .amount:contains("0.80")', + run: function () {}, }]); steps = steps.concat(finish_order()); // test opw-672118 orderline subtotal rounding steps = steps.concat(add_product_to_order('Desk Organizer')); - steps = steps.concat(generate_product_screen_keypad_steps('.999')); // sets orderline qty - steps = steps.concat(verify_order_total('5.09')); + steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '1.0'})); + steps = steps.concat(press_product_numpad('.')) + steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.0', price: '0.0'})); + steps = steps.concat(press_product_numpad('9')) + steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.9', price: '4.59'})); + steps = steps.concat(press_product_numpad('9')) + steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.99', price: '5.05'})); + steps = steps.concat(press_product_numpad('9')) + steps = steps.concat(selected_orderline_has({product: 'Desk Organizer', quantity: '0.999', price: '5.09'})); steps = steps.concat(goto_payment_screen_and_select_payment_method()); - steps = steps.concat(generate_payment_screen_keypad_steps("10")); + steps = steps.concat(selected_payment_has('Cash', '5.09')); steps = steps.concat(finish_order()); // Test fiscal position one2many map (align with backend) steps = steps.concat(add_product_to_order('Letter Tray')); + steps = steps.concat(selected_orderline_has({product: 'Letter Tray', quantity: '1.0'})); steps = steps.concat(verify_order_total('5.28')); steps = steps.concat(set_fiscal_position_on_order('FP-POS-2M')); steps = steps.concat(verify_order_total('5.52')); diff --git a/addons/point_of_sale/tests/test_frontend.py b/addons/point_of_sale/tests/test_frontend.py index 4f99b032abf..a65d4d6bd9e 100644 --- a/addons/point_of_sale/tests/test_frontend.py +++ b/addons/point_of_sale/tests/test_frontend.py @@ -489,11 +489,11 @@ class TestUi(TestPointOfSaleHttpCommon): # this you end up with js, css but no qweb. self.env['ir.module.module'].search([('name', '=', 'point_of_sale')], limit=1).state = 'installed' - self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_pricelist', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_basic_order', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ProductScreenTour', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'PaymentScreenTour', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ReceiptScreenTour', login="admin", step_delay=50) + self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_pricelist', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_basic_order', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ProductScreenTour', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'PaymentScreenTour', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ReceiptScreenTour', login="admin") for order in self.env['pos.order'].search([]): self.assertEqual(order.state, 'paid', "Validated order has payment of " + str(order.amount_paid) + " and total of " + str(order.amount_total)) diff --git a/addons/pos_hr/static/tests/tours/PosHrTour.js b/addons/pos_hr/static/tests/tours/PosHrTour.js index dea8b4a2baf..df4cc2be6da 100644 --- a/addons/pos_hr/static/tests/tours/PosHrTour.js +++ b/addons/pos_hr/static/tests/tours/PosHrTour.js @@ -19,7 +19,9 @@ odoo.define('point_of_sale.tour.PosHr', function (require) { SelectionPopup.check.hasSelectionItem('Mitchell Admin'); SelectionPopup.do.clickItem('Pos Employee1'); NumberPopup.check.isShown(); - NumberPopup.do.pressNumpad('2 5 8 1'); + NumberPopup.do.pressNumpad('2 5'); + NumberPopup.check.inputShownIs('••'); + NumberPopup.do.pressNumpad('8 1'); NumberPopup.check.inputShownIs('••••'); NumberPopup.do.clickConfirm(); ErrorPopup.check.isShown(); @@ -27,7 +29,9 @@ odoo.define('point_of_sale.tour.PosHr', function (require) { PosHr.do.clickLoginButton(); SelectionPopup.do.clickItem('Pos Employee1'); NumberPopup.check.isShown(); - NumberPopup.do.pressNumpad('2 5 8 0'); + NumberPopup.do.pressNumpad('2 5'); + NumberPopup.check.inputShownIs('••'); + NumberPopup.do.pressNumpad('8 0'); NumberPopup.check.inputShownIs('••••'); NumberPopup.do.clickConfirm(); ProductScreen.check.isShown(); @@ -36,7 +40,13 @@ odoo.define('point_of_sale.tour.PosHr', function (require) { SelectionPopup.do.clickItem('Mitchell Admin'); PosHr.check.cashierNameIs('Mitchell Admin'); PosHr.do.clickLockButton(); - PosHr.exec.login('Pos Employee2', '1234'); + PosHr.do.clickLoginButton(); + SelectionPopup.do.clickItem('Pos Employee2'); + NumberPopup.do.pressNumpad('1 2'); + NumberPopup.check.inputShownIs('••'); + NumberPopup.do.pressNumpad('3 4'); + NumberPopup.check.inputShownIs('••••'); + NumberPopup.do.clickConfirm(); ProductScreen.check.isShown(); Tour.register('PosHrTour', { test: true, url: '/pos/web' }, getSteps()); diff --git a/addons/pos_hr/tests/test_frontend.py b/addons/pos_hr/tests/test_frontend.py index a28f057e327..9afcd78897a 100644 --- a/addons/pos_hr/tests/test_frontend.py +++ b/addons/pos_hr/tests/test_frontend.py @@ -50,5 +50,4 @@ class TestUi(TestPosHrHttpCommon): "/pos/web?config_id=%d" % self.main_pos_config.id, "PosHrTour", login="admin", - step_delay=50, ) diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js index 587fe6e2d7c..87b599c9428 100644 --- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js @@ -153,15 +153,24 @@ odoo.define('pos_restaurant.FloorScreen', function (require) { }); if (!confirmed) return; try { + const originalSelectedTableId = this.state.selectedTableId; await this.rpc({ model: 'restaurant.table', method: 'create_from_ui', - args: [{ active: false, id: this.state.selectedTableId }], + args: [{ active: false, id: originalSelectedTableId }], }); this.activeFloor.tables = this.activeTables.filter( - (table) => table.id !== this.state.selectedTableId + (table) => table.id !== originalSelectedTableId ); - this.state.selectedTableId = null; + // Value of an object can change inside async function call. + // Which means that in this code block, the value of `state.selectedTableId` + // before the await call can be different after the finishing the await call. + // Since we wanted to disable the selected table after deletion, we should be + // setting the selectedTableId to null. However, we only do this if nothing + // else is selected during the rpc call. + if (this.state.selectedTableId === originalSelectedTableId) { + this.state.selectedTableId = null; + } } catch (error) { if (error.message.code < 0) { await this.showPopup('OfflineErrorPopup', { diff --git a/addons/pos_restaurant/static/tests/tours/ControlButtons.tour.js b/addons/pos_restaurant/static/tests/tours/ControlButtons.tour.js index 102ff280977..f26d4f79b29 100644 --- a/addons/pos_restaurant/static/tests/tours/ControlButtons.tour.js +++ b/addons/pos_restaurant/static/tests/tours/ControlButtons.tour.js @@ -16,16 +16,16 @@ odoo.define('pos_restaurant.tour.ControlButtons', function (require) { // Test TransferOrderButton FloorScreen.do.clickTable('T2'); - ProductScreen.exec.addOrderline('Water', '5.0', '2.0'); + ProductScreen.exec.addOrderline('Water', '5', '2', '10.0'); ProductScreen.do.clickTransferButton(); FloorScreen.do.clickTable('T4'); - ProductScreen.do.clickOrderline('Water', '5.0', '2.0'); + ProductScreen.do.clickOrderline('Water', '5', '2'); Chrome.do.backToFloor(); FloorScreen.do.clickTable('T2'); ProductScreen.check.orderIsEmpty(); Chrome.do.backToFloor(); FloorScreen.do.clickTable('T4'); - ProductScreen.do.clickOrderline('Water', '5.0', '2.0'); + ProductScreen.do.clickOrderline('Water', '5', '2'); // Test SplitBillButton ProductScreen.do.clickSplitBillButton(); @@ -36,9 +36,8 @@ odoo.define('pos_restaurant.tour.ControlButtons', function (require) { TextAreaPopup.check.isShown(); TextAreaPopup.do.inputText('test note'); TextAreaPopup.do.clickConfirm(); - ProductScreen.check.orderlineHasNote('Water', '5.0', 'test note'); - ProductScreen.exec.addOrderline('Water', '8', '1.1'); - ProductScreen.check.selectedOrderlineHas('Water', '8', '8.80'); + ProductScreen.check.orderlineHasNote('Water', '5', 'test note'); + ProductScreen.exec.addOrderline('Water', '8', '1', '8.0'); // Test PrintBillButton ProductScreen.do.clickPrintBillButton(); diff --git a/addons/pos_restaurant/static/tests/tours/FloorScreen.tour.js b/addons/pos_restaurant/static/tests/tours/FloorScreen.tour.js index 4ece19fec4b..93a7a2c8ea6 100644 --- a/addons/pos_restaurant/static/tests/tours/FloorScreen.tour.js +++ b/addons/pos_restaurant/static/tests/tours/FloorScreen.tour.js @@ -35,6 +35,7 @@ odoo.define('pos_restaurant.tour.FloorScreen', function (require) { FloorScreen.do.clickFloor('Main Floor'); FloorScreen.check.editModeIsActive(false); FloorScreen.do.clickEdit(); + FloorScreen.check.editModeIsActive(true); // test add table FloorScreen.do.clickAddTable(); @@ -47,13 +48,18 @@ odoo.define('pos_restaurant.tour.FloorScreen', function (require) { // test duplicate table FloorScreen.do.clickDuplicate(); - FloorScreen.do.clickRename(); - TextInputPopup.do.inputText('T101'); + // new table is already named T101 FloorScreen.check.selectedTableIs('T101'); + FloorScreen.do.clickRename(); + TextInputPopup.check.isShown(); + TextInputPopup.do.inputText('T1111'); + TextInputPopup.do.clickConfirm(); + FloorScreen.check.selectedTableIs('T1111'); // switch floor, switch back and check if // the new tables are still there FloorScreen.do.clickFloor('Second Floor'); + FloorScreen.check.editModeIsActive(false); FloorScreen.check.hasTable('T3'); FloorScreen.check.hasTable('T1'); @@ -62,26 +68,31 @@ odoo.define('pos_restaurant.tour.FloorScreen', function (require) { FloorScreen.check.hasTable('T4'); FloorScreen.check.hasTable('T5'); FloorScreen.check.hasTable('T100'); - FloorScreen.check.hasTable('T101'); + FloorScreen.check.hasTable('T1111'); // test delete table FloorScreen.do.clickEdit(); + FloorScreen.check.editModeIsActive(true); FloorScreen.do.clickTable('T2'); + FloorScreen.check.selectedTableIs('T2'); FloorScreen.do.clickTrash(); Chrome.do.confirmPopup(); // change number of seats FloorScreen.do.clickTable('T4'); + FloorScreen.check.selectedTableIs('T4'); FloorScreen.do.clickSeats(); - NumberPopup.do.pressNumpad('Backspace 1 0'); + NumberPopup.do.pressNumpad('Backspace 9'); + NumberPopup.check.inputShownIs('9'); NumberPopup.do.clickConfirm(); - FloorScreen.check.tableSeatIs('T4', '10'); + FloorScreen.check.tableSeatIs('T4', '9'); // change shape FloorScreen.do.changeShapeTo('round'); // Opening product screen in main floor should go back to main floor FloorScreen.do.clickEdit(); + FloorScreen.check.editModeIsActive(false); FloorScreen.check.hasTable('T4'); FloorScreen.do.clickTable('T4'); ProductScreen.check.isShown(); diff --git a/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js b/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js index 9eb138bbb9b..cf09ebf0a4b 100644 --- a/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js +++ b/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js @@ -15,9 +15,9 @@ odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) { startSteps(); FloorScreen.do.clickTable('T2'); - ProductScreen.exec.addOrderline('Water', '5', '1.2'); - ProductScreen.exec.addOrderline('Minute Maid', '3', '1.2'); - ProductScreen.exec.addOrderline('Coca-Cola', '1', '1.2'); + ProductScreen.exec.addOrderline('Water', '5', '2', '10.0'); + ProductScreen.exec.addOrderline('Minute Maid', '3', '2', '6.0'); + ProductScreen.exec.addOrderline('Coca-Cola', '1', '2', '2.0'); ProductScreen.do.clickSplitBillButton(); // Check if the screen contains all the orderlines @@ -31,10 +31,10 @@ odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) { SplitBillScreen.do.clickOrderline('Water'); SplitBillScreen.do.clickOrderline('Water'); SplitBillScreen.check.orderlineHas('Water', '5', '3'); - SplitBillScreen.check.subtotalIs('3.60') + SplitBillScreen.check.subtotalIs('6.0') SplitBillScreen.do.clickOrderline('Coca-Cola'); SplitBillScreen.check.orderlineHas('Coca-Cola', '1', '1'); - SplitBillScreen.check.subtotalIs('4.80') + SplitBillScreen.check.subtotalIs('8.0') // click pay to split, go back to check the lines SplitBillScreen.do.clickPay(); diff --git a/addons/pos_restaurant/tests/test_frontend.py b/addons/pos_restaurant/tests/test_frontend.py index f13cec07767..5c740c4cda2 100644 --- a/addons/pos_restaurant/tests/test_frontend.py +++ b/addons/pos_restaurant/tests/test_frontend.py @@ -158,12 +158,12 @@ class TestFrontend(odoo.tests.HttpCase): self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False) - self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync', login="admin", step_delay=50) + self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync', login="admin") self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'draft')])) self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'paid')])) - self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync_second_login', login="admin", step_delay=50) + self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync_second_login', login="admin") self.assertEqual(0, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'draft')])) self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 2.2), ('state', '=', 'draft')])) @@ -171,9 +171,9 @@ class TestFrontend(odoo.tests.HttpCase): def test_02_others(self): self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False) - self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'SplitBillScreenTour', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'ControlButtonsTour', login="admin", step_delay=50) - self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'FloorScreenTour', login="admin", step_delay=50) + self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'SplitBillScreenTour', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'ControlButtonsTour', login="admin") + self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'FloorScreenTour', login="admin") def test_03_order_management_integration(self): self.pos_config.write({'manage_orders': True}) |
