Dart - Polymer Unit Testing. Not able to reference dom elements after click event

198 views Asked by At
Not able to reference dom elements.

Most of the test case works except for the last expectation in ClickSignInButton when I want to make sure I can evaluate error message div when form is submitted without any data.

expect(document.querySelector('qme-header').shadowRoot .querySelector('#headerErrorDiv'), isNotNull); always fails and headerErrorDiv is null even though its there in the div.

Code:

import 'package:test/test.dart';
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'dart:async';

main() {
   initPolymer().then((zone) => zone.run(() {
     return Polymer.onReady.then((_) {
       group('Header Form Elements Are Available', () {
         test(("CheckSignInFormItems"), () {
            expect(querySelector('qme-header').shadowRoot
            .querySelector('#emailField'), isNotNull);
            expect(querySelector('qme-header').shadowRoot
             .querySelector('#passwordField'), isNotNull);
            expect(querySelector('qme-header').shadowRoot
             .querySelector('#signInButton'), isNotNull);
          });
          test(("CheckRegisterForgotItems"), () {
            expect(querySelector('qme-header').shadowRoot
              .querySelector('#registerButton'), isNotNull);
            expect(querySelector('qme-header').shadowRoot
              .querySelector('#forgotButton'), isNotNull);
          });
         });

         group('Header Form Click Sign In Button', () {
           test(("ClickSignInButton"), () {
             (querySelector('qme-header').shadowRoot
             .querySelector('#emailField') as InputElement).value = "";
            (querySelector('qme-header').shadowRoot
              .querySelector('#passwordField') as InputElement).value =  
                "";

           Timer.run(expectAsync(() {
            (querySelector('qme-header').shadowRoot
            .querySelector('#signInButton') as ButtonElement).click();
            expect(document.querySelector('qme-header').shadowRoot
             .querySelector('#headerErrorDiv'), isNotNull);
          }));
         });
       });
      });
     }));
   }

Hi Günter, Thank you for your time, I adjusted my code based on your comments and it should work, however I think I am messing up the way I am using polymer templates.

pubspec.yaml

   environment:
          sdk: '>=1.0.0 <2.0.0'
   dependencies:
          bootstrap: ^3.3.4
          browser: '>=0.10.0 <0.11.0'
          polymer: '>=0.16.0 <0.17.0'
          test: '>=0.12.3'
    transformers:
        - polymer:
            inline_stylesheets:
               packages/bootstrap/css/bootstrap.css: false
               packages/bootstrap/css/bootstrap-theme.css: false
            entry_points:
              - web/index.html
              - test/qme_header_test.html
         - test/pub_serve:
              $include: test/**_test{.*,}.dart

header.html

       <polymer-element name="qme-header">
         <div class="container">
             <div class="navbar-header"><a class="navbar-brand"  
              href="#"><span>QMe Application</span></a></div>
              <template if="{{usingHeaderForm}}">
                    <div id="navbar" class="navbar-collapse collapse" >
                      <form on-submit="{{validateSignInForm}}" 
               class="navbar-form navbar-right">
                          <div class="form-group">
                               <input type="text" id="emailField" 
               value="{{qmeSignIn.userEmail}}" placeholder="Email" 
               class="form-control">
                          </div>
                          <div class="form-group">
                              <input type="password" id="passwordField" 
                value="{{qmeSignIn.userPassword}}"  
                placeholder="Password" class="form-control">
                          </div>
                          <button id="signInButton" type="submit" 
                 class="btn btn-success btn-sm">Sign in</button>
                          &nbsp;&nbsp;&nbsp;&nbsp;
                          <button id="registerButton" class="btn btn-
                   info btn-xs" type="button-small">Register</button>
                          &nbsp;
                          <button id="forgotButton" class="btn btn-info 
                 btn-xs" type="button-small">Forgot Password</button>
                      </form>
                    </div>
              </template>
              <template if="{{!usingHeaderForm}}">
                    <p>Hello login complete</p>
              </template>

header.dart

       library qme_header;

       import 'package:polymer/polymer.dart';
       import 'dart:html';
       import 'package:qme/views/qme_error.dart';

       @CustomTag('qme-header')
       class QmeHeader extends PolymerElement {
       @published QMeSignIn qmeSignIn;

       @observable bool usingHeaderForm = true;

       @observable QmeErrorHolder qmeErrorHolder;

       QmeHeader.created() : super.created() {
          qmeSignIn = new QMeSignIn();
          qmeErrorHolder = QmeErrorHolder.instance;
        }

        toggleFormDisplay() {
          usingHeaderForm = !usingHeaderForm;
         }

          performLogin() {
           toggleFormDisplay();
           }

          bool validateSignInEmail() {
            if (qmeSignIn.userEmail.length == 0) {
             qmeErrorHolder.headerErrorMessage = "Valid user email 
             required";
             return false;
            }
            qmeErrorHolder.headerErrorMessage = '';
            return true;
           }

           bool validateSignInPassword() {
           if (qmeSignIn.userPassword.length == 0) {
              qmeErrorHolder.headerErrorMessage = "Valid user password 
           required";
            return false;
           }
           qmeErrorHolder.headerErrorMessage = '';
           return true;
           }

         validateSignInForm(Event event, Object detail, Node sender) {
          event.preventDefault();
         if (validateSignInEmail() && validateSignInPassword()) {
          print("Submit");
          performLogin();
           qmeErrorHolder.headerError = false;
          } else {
           qmeErrorHolder.headerError = true;
         }
        }
         }

        class QMeSignIn extends Observable {
            @observable String userEmail;
            @observable String userPassword;
            QMeSignIn([this.userEmail = "", this.userPassword = ""]);
           }

error.html

         <polymer-element name="qme-error">
          <template>
           <template if="{{qmeErrorHolder.headerError}}">
             <div class="container">
                  <div id="headerErrorDiv" class="alert alert-danger" 
            role="alert">{{qmeErrorHolder.headerErrorMessage}}</div>
              </div>
            </template>
         </template>
          <script type="application/dart" src="qme_error.dart">
          </script>
         </polymer-element>

error.dart

         library qme_error;

         import 'package:polymer/polymer.dart';

         @CustomTag('qme-error')
         class QmeError extends PolymerElement {
            @observable QmeErrorHolder qmeErrorHolder;

            QmeError.created() : super.created() {
            qmeErrorHolder = QmeErrorHolder.instance;
           }
          }

          class QmeErrorHolder extends Observable {
             @observable bool headerError;

             @observable String headerErrorMessage;

             static final QmeErrorHolder _instance = new    
             QmeErrorHolder._internal();

             static QmeErrorHolder get instance => _instance;

             QmeErrorHolder._internal();
            }

headertest.html

            <html>
             <head>
              <link rel="import" 
              href="../packages/polymer/polymer.html">
              <link rel="import"  
              href="../packages/qme/views/qme_header.html" >
               <link rel="import" 
              href="../packages/qme/views/qme_error.html" >
             <link rel="stylesheet" 
              href="packages/bootstrap/css/bootstrap.css">
              <link rel="stylesheet" 
               href="packages/bootstrap/css/bootstrap-theme.css">
                <script type="application/dart" 
               src="qme_header_test.dart"></script>
            <script data-pub-inline src="packages/test/dart.js"> 
              </script>
            </head>
              <body>
                <qme-header></qme-header>
                <qme-error></qme-error>
              </body>
             </html> 

headertest.dart

             @whenPolymerReady
             void runTests() {

               group('Header Form Click Sign In Button', () {
                   test(("ClickSignInButton"), () {
                 (querySelector('qme-header::shadow #emailField ') as         
                   InputElement).value ="";
             (querySelector(
                  'qme-header::shadow #passwordField') as 
                  InputElement).value = "";
                (querySelector('qme-header::shadow #signInButton') as 
                  ButtonElement)
                  .click();
            expect(
                 document.querySelector('qme-error::shadow #headerErrorDiv'), isNotNull);
            });
           });
              }

index.html

          <html>
            <head>
             <link rel="stylesheet" 
               href="packages/bootstrap/css/bootstrap.css">
               <link rel="stylesheet" 
               href="packages/bootstrap/css/bootstrap-theme.css">
             <link rel="stylesheet" href="styles/main.css">
             <link rel="import" 
           href="packages/qme/views/qme_header.html">
            <link rel="import" 
             href="packages/qme/views/qme_error.html">
           </head>
              <body>
              <qme-header></qme-header>
                 <qme-error></qme-error>

            <script src="packages/bootstrap/jquery/jquery.js"></script>
            <script src="packages/bootstrap/js/bootstrap.js"></script>
            <script data-pub-inline src="packages/browser/dart.js">    
             </script>
             <script type="application/dart">export 
             'package:polymer/init.dart';</script>
          </body>
            </html> 

Running index.html in Dartium works, however header test fails with null for headerErrorDiv. I know I am messing up with Polymer template and having gobal error holder most likely, but it works when index.html runs in Dartium and fails test cases when headertest.html is run.

1

There are 1 answers

0
Günter Zöchbauer On BEST ANSWER

At first, I think you should add the @whenPolymerReady annotation to main() instead of your Polymer initialization code.

Instead of

expect(document.querySelector('qme-header').shadowRoot
         .querySelector('#headerErrorDiv'), isNotNull);

you could use

expect(document.querySelector('qme-header::shadow #headerErrorDiv'), isNotNull);

I don't see a problem in your cod. Can you please provide a complete example that allows to reproduce your problem (incl HTML and pubspec.yaml)

headerErrorDiv only exists if qmeErrorHolder.headerError is true

I think you should ensure the test files end with _test(.dart|.html) to be recognized by the testrunner pub run test

You need to change the Dart script tag to x-link-dart to make the test work with the testrunner (and back to <script> when you want to run it directly)

AFAIK If your test needs additional files like your component files you need to run pub serve test and pass the port to pub run test (see readme of the test package for more details)