diff --git a/modules/receipt/js/commerce_pos_receipt.js b/modules/receipt/js/commerce_pos_receipt.js index 95d590e..1018b78 100644 --- a/modules/receipt/js/commerce_pos_receipt.js +++ b/modules/receipt/js/commerce_pos_receipt.js @@ -26,14 +26,21 @@ * XMLHttpRequest status. */ Drupal.AjaxCommands.prototype.printReceipt = function (ajax, response, status) { - $(response.content).print({ - globalStyles: false, - stylesheet: drupalSettings.commercePosReceipt.cssUrl, - deferred: $.Deferred().done(function(){ - // Sloppy, should probaby be nice and scalable, but that might never be needed - $('.commerce-pos-receipt-button-done').click(); - }) - }); + // If jQuery.print does not exist then this will not be a function. This + // can occur if the libraries is not yet downloaded and under test. + if (typeof $(response.content).print === "function") { + $(response.content).print({ + globalStyles: false, + stylesheet: drupalSettings.commercePosReceipt.cssUrl, + deferred: $.Deferred().done(function () { + // Sloppy, should probaby be nice and scalable, but that might never be needed + $('.commerce-pos-receipt-button-done').click(); + }) + }); + } + else { + $('.commerce-pos-receipt-button-done').click(); + } }; /** @@ -43,7 +50,14 @@ var printed = false; Drupal.behaviors.catchSubmits = { attach: function (context, settings) { - $('.commerce-pos-receipt-button', context).click( function (e) { + // If jQuery.print does not exist then this will not be a function. This + // can occur if the libraries is not yet downloaded and under test. + if (typeof $().print !== "function") { + // nothing to do as there is no jQuery.print library. + return; + } + + $('.commerce-pos-receipt-button', context).click( function (e) { // Normally you would use .once() here, but it applies at the end, // and because of the chaining nature of our ajax, it doesn't fire until it is too late // and we've clicked the button again and we're in a loop diff --git a/modules/receipt/tests/src/FunctionalJavascript/PosReceiptTest.php b/modules/receipt/tests/src/FunctionalJavascript/PosReceiptTest.php new file mode 100644 index 0000000..0e7b88b --- /dev/null +++ b/modules/receipt/tests/src/FunctionalJavascript/PosReceiptTest.php @@ -0,0 +1,84 @@ +setUpStore(); + // @todo work out the expected permissions to view products etc... + $this->drupalLogin($this->rootUser); + } + + /** + * Tests receipt function. + */ + public function testReceipt() { + $web_assert = $this->assertSession(); + $this->drupalGet('admin/commerce/pos/main'); + // There is only one register. + $web_assert->fieldValueEquals('register', 1); + $web_assert->pageTextContains('Test register'); + $this->drupalPostForm(NULL, [], 'Select Register'); + + // Now we should be able to select order items. + $autocomplete_field = $this->getSession()->getPage()->findField('order_items[target_id][product_selector]'); + $autocomplete_field->setValue('Jum'); + $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), 'p'); + $web_assert->waitOnAutocomplete(); + $results = $this->getSession()->getPage()->findAll('css', '.ui-autocomplete li'); + // Click on of the auto-complete. + $results[0]->click(); + $web_assert->assertWaitOnAjaxRequest(); + + // We now have a product selected and current order is in progress. + $this->drupalGet('admin/commerce/orders'); + $web_assert->elementsCount('css', '.views-view-table tbody tr', 1); + $web_assert->pageTextContains('Point of Sale'); + $web_assert->pageTextContains('Draft'); + $web_assert->pageTextContains('Edit'); + $web_assert->pageTextNotContains('Show receipt'); + + // Go back to the order + $this->drupalGet('admin/commerce/pos/main'); + // Go to the payment page. + $this->click('.commerce-pos input[name="op"]'); + $this->click('input[name="commerce-pos-pay-keypad-add"]'); + $this->click('input[name="commerce-pos-finish"]'); + $this->waitForAjaxToFinish(); + // We now have a complete order and new draft order. + $this->drupalGet('admin/commerce/orders'); + // The first row has a Show receipt action and the second does not. + $web_assert->elementContains('xpath', '//table[contains(@class, "views-view-table")]/tbody/tr[1]', 'Show receipt'); + $web_assert->elementNotContains('xpath', '//table[contains(@class, "views-view-table")]/tbody/tr[2]', 'Show receipt'); + } + + /** + * Waits for jQuery to become active and animations to complete. + */ + protected function waitForAjaxToFinish() { + $condition = "(0 === jQuery.active && 0 === jQuery(':animated').length)"; + $this->assertJsCondition($condition, 10000); + } + +} diff --git a/tests/src/Functional/CommercePosCreateStoreTrait.php b/tests/src/Functional/CommercePosCreateStoreTrait.php index cf63b9c..ca53817 100644 --- a/tests/src/Functional/CommercePosCreateStoreTrait.php +++ b/tests/src/Functional/CommercePosCreateStoreTrait.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\commerce_pos\Functional; +use Drupal\commerce_pos\Entity\Register; use Drupal\commerce_price\Price; use Drupal\commerce_product\Entity\Product; use Drupal\commerce_product\Entity\ProductVariation; @@ -54,4 +55,49 @@ trait CommercePosCreateStoreTrait { return $product; } + /** + * Creates a store with some products. + */ + protected function setUpStore() { + // Initial store set up. + $test_store = $this->createStore('POS test store', 'pos_test_store@example.com', 'physical'); + + $register = Register::create([ + 'store_id' => $test_store->id(), + 'name' => 'Test register', + 'cash' => new Price('1000.00', 'USD'), + ]); + $register->save(); + + $variations = [ + $this->createProductionVariation([ + 'title' => 'T-shirt XL', + 'price' => new Price("23.20", 'USD'), + ]), + $this->createProductionVariation(['title' => 'T-shirt L']), + $this->createProductionVariation(['title' => 'T-shirt M']), + ]; + + $this->createProduct([ + 'variations' => $variations, + 'title' => 'T-shirt', + 'stores' => [$test_store], + ]); + + $variations = [ + $this->createProductionVariation([ + 'title' => 'Jumper XL', + 'price' => new Price("50", 'USD'), + ]), + $this->createProductionVariation(['title' => 'Jumper L']), + $this->createProductionVariation(['title' => 'Jumper M']), + ]; + + $this->createProduct([ + 'variations' => $variations, + 'title' => 'Jumper', + 'stores' => [$test_store], + ]); + } + } diff --git a/tests/src/FunctionalJavascript/PosFormTest.php b/tests/src/FunctionalJavascript/PosFormTest.php index 70c244d..87c26ed 100644 --- a/tests/src/FunctionalJavascript/PosFormTest.php +++ b/tests/src/FunctionalJavascript/PosFormTest.php @@ -2,8 +2,6 @@ namespace Drupal\Tests\commerce_pos\FunctionalJavascript; -use Drupal\commerce_pos\Entity\Register; -use Drupal\commerce_price\Price; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\FunctionalJavascriptTests\JavascriptTestBase; use Drupal\Tests\commerce_pos\Functional\CommercePosCreateStoreTrait; @@ -30,47 +28,7 @@ class PosFormTest extends JavascriptTestBase { */ protected function setUp() { parent::setUp(); - - // Initial store set up. - $test_store = $this->createStore('POS test store', 'pos_test_store@example.com', 'physical'); - - $register = Register::create([ - 'store_id' => $test_store->id(), - 'name' => 'Test register', - 'cash' => new Price('1000.00', 'USD'), - ]); - $register->save(); - - $variations = [ - $this->createProductionVariation([ - 'title' => 'T-shirt XL', - 'price' => new Price("23.20", 'USD'), - ]), - $this->createProductionVariation(['title' => 'T-shirt L']), - $this->createProductionVariation(['title' => 'T-shirt M']), - ]; - - $this->createProduct([ - 'variations' => $variations, - 'title' => 'T-shirt', - 'stores' => [$test_store], - ]); - - $variations = [ - $this->createProductionVariation([ - 'title' => 'Jumper XL', - 'price' => new Price("50", 'USD'), - ]), - $this->createProductionVariation(['title' => 'Jumper L']), - $this->createProductionVariation(['title' => 'Jumper M']), - ]; - - $this->createProduct([ - 'variations' => $variations, - 'title' => 'Jumper', - 'stores' => [$test_store], - ]); - + $this->setUpStore(); // @todo work out the expected permissions to view products etc... $this->drupalLogin($this->rootUser); }