Dart - 聚合物单元测试。单击事件后无法引用 dom 个元素
Dart - Polymer Unit Testing. Not able to reference dom elements after click event
Not able to reference dom elements.
除了 ClickSignInButton
中的最后一个预期之外,大多数测试用例都有效,当我想确保在提交没有任何数据的表单时我可以评估错误消息 div。
expect(document.querySelector('qme-header').shadowRoot
.querySelector('#headerErrorDiv'), isNotNull);
总是失败并且 headerErrorDiv
为空,即使它在 div.
中也是如此
代码:
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);
}));
});
});
});
}));
}
您好 Günter,感谢您抽出宝贵时间,我根据您的意见调整了我的代码,它应该可以工作,但是我认为我使用聚合物模板的方式搞砸了。
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>
<button id="registerButton" class="btn btn-
info btn-xs" type="button-small">Register</button>
<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>
运行 index.html
在 Dartium 中有效,但是 header 测试失败,headerErrorDiv
为 null。我知道我搞砸了 Polymer 模板并且最有可能拥有 gobal error holder,但是当 index.html
运行s 在 Dartium 中时它可以工作并且当 headertest.html
是 运行 时测试用例失败.
起初,我认为您应该将 @whenPolymerReady
注释添加到 main()
而不是您的 Polymer 初始化代码。
而不是
expect(document.querySelector('qme-header').shadowRoot
.querySelector('#headerErrorDiv'), isNotNull);
你可以使用
expect(document.querySelector('qme-header::shadow #headerErrorDiv'), isNotNull);
我没有发现你的问题
鳕鱼。您能否提供一个完整的示例来重现您的问题(包括 HTML 和 pubspec.yaml)
headerErrorDiv
仅在 qmeErrorHolder.headerError
为真时存在
我认为你应该确保以 _test
(.dart
|.html
) 结尾的测试文件被测试运行ner pub run test
识别
您需要将 Dart 脚本标签更改为 x-link-dart
以使测试与测试 运行 一起工作(并在您想要 [=42= 时返回 <script>
]直接)
AFAIK 如果您的测试需要其他文件,例如您的组件文件,您需要 运行 pub serve test
并将端口传递给 pub run test
(有关更多详细信息,请参阅测试包的自述文件)
Not able to reference dom elements.
除了 ClickSignInButton
中的最后一个预期之外,大多数测试用例都有效,当我想确保在提交没有任何数据的表单时我可以评估错误消息 div。
expect(document.querySelector('qme-header').shadowRoot
.querySelector('#headerErrorDiv'), isNotNull);
总是失败并且 headerErrorDiv
为空,即使它在 div.
代码:
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);
}));
});
});
});
}));
}
您好 Günter,感谢您抽出宝贵时间,我根据您的意见调整了我的代码,它应该可以工作,但是我认为我使用聚合物模板的方式搞砸了。
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>
<button id="registerButton" class="btn btn-
info btn-xs" type="button-small">Register</button>
<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>
运行 index.html
在 Dartium 中有效,但是 header 测试失败,headerErrorDiv
为 null。我知道我搞砸了 Polymer 模板并且最有可能拥有 gobal error holder,但是当 index.html
运行s 在 Dartium 中时它可以工作并且当 headertest.html
是 运行 时测试用例失败.
起初,我认为您应该将 @whenPolymerReady
注释添加到 main()
而不是您的 Polymer 初始化代码。
而不是
expect(document.querySelector('qme-header').shadowRoot
.querySelector('#headerErrorDiv'), isNotNull);
你可以使用
expect(document.querySelector('qme-header::shadow #headerErrorDiv'), isNotNull);
我没有发现你的问题 鳕鱼。您能否提供一个完整的示例来重现您的问题(包括 HTML 和 pubspec.yaml)
headerErrorDiv
仅在 qmeErrorHolder.headerError
为真时存在
我认为你应该确保以 _test
(.dart
|.html
) 结尾的测试文件被测试运行ner pub run test
识别
您需要将 Dart 脚本标签更改为 x-link-dart
以使测试与测试 运行 一起工作(并在您想要 [=42= 时返回 <script>
]直接)
AFAIK 如果您的测试需要其他文件,例如您的组件文件,您需要 运行 pub serve test
并将端口传递给 pub run test
(有关更多详细信息,请参阅测试包的自述文件)