How to test form submits in Polymer 2 elements without the page refreshing

401 Views Asked by At

I have a Polymer 2 "search" component that contains a form and a text input. The component handles the form submit on the form element using on-submit="_handleFormSubmit", and the handling function calls event.preventDefault(). This works as expected when used in a real app - the form submission isn't handled by the browser and so there is no page refresh. Also, the handler creates a custom search event that's fired on the component. Here is its code:

<link rel="import" href="../bower_components/polymer/polymer-element.html">

<dom-module id="my-search">
  <template>
    <form on-submit="_handleSearchSubmit">
      <input type="text" name="search" placeholder="[[placeholder]]" value="{{searchFor::change}}">
    </form>
  </template>

  <script>
    class MySearch extends Polymer.Element {

      static get is() { return 'my-search'; }

      static get properties() {
        return {
          'placeholder': {
            type: String
          },
          'searchFor': {
            type: String
          }
        }
      }

      _handleSearchSubmit(e) {
        e.preventDefault();
        this.dispatchEvent(new CustomEvent('search', {detail: {searchFor: this.searchFor}}));
      }
    }

    window.customElements.define(MySearch.is, MySearch);
  </script>
</dom-module>

I'm trying to write tests for this component, but I can't seem to stop the form submit from refreshing the test page (and hence infinite test loop) when I try to test the search event. Here is what my test looks like:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">

    <title>my-search-test</title>

    <script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
    <script src="../bower_components/web-component-tester/browser.js"></script>
    <link rel="import" href="../src/my-search.html">
</head>
<body>
    <test-fixture id="mySearchTest">
      <template>
        <my-search></my-search>
      </template>
    </test-fixture>

    <script>
      suite('<my-search>', function() {
        var el;

        setup(function() {
          el = fixture('mySearchTest');
        });

        test('the search event is triggered on form submit', function(done) {
          var formEl = el.shadowRoot.querySelector('form');
          el.addEventListener('search', function(event) {
            done();
          });
          formEl.dispatchEvent(new Event('submit'));
        });

      });
    </script>
  </body>
</html>

I've tried changing formEl.dispatchEvent(new Event('submit')) to formEl.submit() and the same problem occurs, although using the submit() approach seems to refresh the page quicker than firing the event. Also, when firing the event, I get full test output in the console (so it tells me all tests passed) before it refreshes.

Thanks for any help.

1

There are 1 best solutions below

0
On

Okay so it turns out the problem is I'm likely not running tests properly.

I was running the tests by doing a polymer serve and accessing a page like 'http://127.0.0.1:8081/components/myapp/test/my-search.html'.

In Firefox (53.0.3 64bit Ubuntu) this is producing the infinite refreshes.

In Chrome 58 64bit Ubuntu this is working fine.

Accessing 'http://127.0.0.1:8081/components/myapp/test/' and doing a WCT.loadSuites() within 'index.html' to run the test works fine in both browsers, and also outputs a nice test summary in the page body.

I have no idea if the original testing method is meant to work, but when I click on an individual suite from the test index page, the URL uses a ?grep= query string to select the test file, and this also works in both browsers, so I'm guessing not.