Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 8c1f79a

Browse files
vicbvsavkin
authored andcommitted
feat(tests): run tests on all browsers
Changes: - chore(travis): cleanup the configuration - chore(travis): run test on IE10, IE11, Safari6 and Safari7 - fix(ShadowDomComponentFactory): Make Windows & Linux return the same response The "\n" would be stripped on windows platforms resulting in responses having a different content. - refactor(Cookies): code cleanup - fix(Cookies): fix for IE and Safari path should not be null, it would extrapolate to "null" - test(http): disable a flaky expectation - The error message varies across browsers: Dartium -> "Unexpected character" Dart2JS: - Chrome -> "Unexpected token" - Firefox -> "unexpected character" - IE -> "Invalid character" - refactor(NgEvent): code cleanup - text(NgEvent): fix the mousewheel event on IE & Safari - chore(pubspec.yaml): add the browser_detect package - test(ng_form_spec): fix an expectation - test(ng_form_spec): Fix a failing test on IE ref #1309 - refactor(ng_model_spec): code cleanup - test(ng_model_spec): el.selectionStart and el.selectionEnd are handled differently on IE - test(WebPlatform): disable web components tests when shim is needed - test(NgModel): fix input type=color default value - "#000000" for Chrome and Firefox - "" for Safari7 and IE11 - refactor(InputSelect): code cleanup - fix(ng_model_select): IE has its own way of handling options - test(select multiple): Need to explicitely select option on IE - test(number inputs): Safari6 keep the previous value on invalid input - test: fix broken Safari 6 animation bugs - test: add missing argument type
1 parent edfd147 commit 8c1f79a

18 files changed

+397
-467
lines changed

.travis.yml

+6-7
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,25 @@ env:
1919
- JOB=unit-stable
2020
CHANNEL=stable
2121
TESTS=dart2js
22-
BROWSERS=SL_Chrome,SL_Firefox
22+
BROWSERS=SL_Chrome,SL_Firefox,SL_IE10,SL_IE11,SL_Safari6,SL_Safari7
2323
- JOB=unit-dev
2424
CHANNEL=dev
2525
TESTS=dart2js
26-
BROWSERS=SL_Chrome,SL_Firefox
26+
BROWSERS=SL_Chrome,SL_Firefox,SL_IE10,SL_IE11,SL_Safari6,SL_Safari7
2727
- JOB=e2e-g3stable
2828
CHANNEL=stable
29-
BROWSERS=DartiumWithWebPlatform,SL_Chrome
29+
BROWSERS=DartiumWithWebPlatform,SL_Chrome,SL_Firefox,SL_IE10,SL_IE11,SL_Safari6,SL_Safari7
3030
USE_G3=YES
3131
- JOB=e2e-stable
3232
CHANNEL=stable
33-
BROWSERS=DartiumWithWebPlatform,SL_Chrome
33+
BROWSERS=DartiumWithWebPlatform,SL_Chrome,SL_Firefox,SL_IE10,SL_IE11,SL_Safari6,SL_Safari7
3434
- JOB=e2e-dev
3535
CHANNEL=dev
36-
BROWSERS=DartiumWithWebPlatform,SL_Chrome
36+
BROWSERS=DartiumWithWebPlatform,SL_Chrome,SL_Firefox,SL_IE10,SL_IE11,SL_Safari6,SL_Safari7
3737
global:
38-
- FIREFOX_VERSION="30.0"
39-
- CHROME_VERSION="35.0"
4038
- secure: AKoqpZ699egF0i4uT/FQ5b4jIc0h+KVbhtVCql0uFxwFIl2HjOYgDayrUCAf6USfpW0LghZxJJhBamWOl/505eNSe9HvEd8JLg/to+1Fo9xi9llsu5ehmNH31/5pue4EvsrVuEap1qqL6/BNwI2cAryayU0p5tV0g8gL5h4IxG8=
4139
- LOGS_DIR=/tmp/angular-build/logs
40+
# Sauce
4241
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
4342
- SAUCE_USERNAME=angular-ci
4443
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987

karma.conf.js

+22
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ module.exports = function(config) {
8080
browserName: 'firefox',
8181
version: '30'
8282
},
83+
'SL_Safari6': {
84+
base: 'SauceLabs',
85+
browserName: 'safari',
86+
version: '6'
87+
},
88+
'SL_Safari7': {
89+
base: 'SauceLabs',
90+
browserName: 'safari',
91+
version: '7'
92+
},
93+
'SL_IE10': {
94+
base: 'SauceLabs',
95+
browserName: 'internet explorer',
96+
platform: 'Windows 8',
97+
version: '10'
98+
},
99+
'SL_IE11': {
100+
base: 'SauceLabs',
101+
browserName: 'internet explorer',
102+
platform: 'Windows 8.1',
103+
version: '11'
104+
},
83105
DartiumWithWebPlatform: {
84106
base: 'Dartium',
85107
flags: ['--enable-experimental-web-platform-features'] }

lib/core_dom/cookies.dart

+46-60
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,44 @@
11
part of angular.core.dom_internal;
22

33
/**
4-
* This class provides low-level acces to the browser's cookies.
5-
* It is not meant to be used directly by applications. Instead
6-
* use the Cookies service.
7-
*
8-
*/
4+
* This class provides low-level access to the browser's cookies. It is not meant to be used
5+
* directly by applications. Use the [Cookies] service instead.
6+
*/
97
@Injectable()
108
class BrowserCookies {
9+
String cookiePath = '/';
10+
1111
ExceptionHandler _exceptionHandler;
1212
dom.Document _document;
13-
14-
var lastCookies = {};
15-
var lastCookieString = '';
16-
var cookiePath;
17-
var baseElement;
13+
var _lastCookies = <String, String>{};
14+
var _lastCookieString = '';
15+
var _baseElement;
1816

1917
BrowserCookies(this._exceptionHandler) {
20-
// Injecting document produces the error 'Caught Compile-time error during mirrored execution:
21-
// <'file:///mnt/data/b/build/slave/dartium-lucid32-full-trunk/build/src/out/Release/gen/blink/
22-
// bindings/dart/dart/html/Document.dart': Error: line 7 pos 3: expression must be a compile-time constant
23-
// @ DocsEditable '
24-
// I have not had time to debug it yet.
2518
_document = dom.document;
26-
2719
var baseElementList = _document.getElementsByName('base');
2820
if (baseElementList.isEmpty) return;
29-
baseElement = baseElementList.first;
21+
_baseElement = baseElementList.first;
3022
cookiePath = _baseHref();
3123
}
3224

33-
var URL_PROTOCOL = new RegExp(r'^https?\:\/\/[^\/]*');
34-
_baseHref() {
35-
var href = baseElement != null ? baseElement.attr('href') : null;
25+
final URL_PROTOCOL = new RegExp(r'^https?\:\/\/[^\/]*');
26+
27+
String _baseHref() {
28+
var href = _baseElement != null ? _baseElement.attr('href') : null;
3629
return href != null ? href.replace(URL_PROTOCOL, '') : '';
3730
}
3831

3932
// NOTE(deboer): This is sub-optimal, see dartbug.com/14281
40-
_unescape(s) => Uri.decodeFull(s);
41-
_escape(s) =>
42-
Uri.encodeFull(s)
43-
.replaceAll('=', '%3D')
44-
.replaceAll(';', '%3B');
45-
46-
_updateLastCookies() {
47-
if (_document.cookie != lastCookieString) {
48-
lastCookieString = _document.cookie;
49-
List<String> cookieArray = lastCookieString.split("; ");
50-
lastCookies = {};
33+
String _unescape(s) => Uri.decodeFull(s);
34+
35+
String _escape(s) => Uri.encodeFull(s).replaceAll('=', '%3D').replaceAll(';', '%3B');
36+
37+
Map<String, String> _updateLastCookies() {
38+
if (_document.cookie != _lastCookieString) {
39+
_lastCookieString = _document.cookie;
40+
List<String> cookieArray = _lastCookieString.split("; ");
41+
_lastCookies = {};
5142

5243
// The first value that is seen for a cookie is the most specific one.
5344
// Values for the same cookie name that follow are for less specific paths.
@@ -56,64 +47,59 @@ class BrowserCookies {
5647
var index = cookie.indexOf('=');
5748
if (index > 0) { //ignore nameless cookies
5849
var name = _unescape(cookie.substring(0, index));
59-
lastCookies[name] = _unescape(cookie.substring(index + 1));
50+
_lastCookies[name] = _unescape(cookie.substring(index + 1));
6051
}
6152
});
6253
}
63-
return lastCookies;
54+
return _lastCookies;
6455
}
6556

66-
/**
67-
* Returns a cookie.
68-
*/
69-
operator[](key) => _updateLastCookies()[key];
57+
/// Return a cookie by name
58+
String operator[](key) => _updateLastCookies()[key];
7059

71-
/**
72-
* Sets a cookie. Setting a cookie to [null] deletes the cookie.
73-
*/
74-
operator[]=(name, value) {
75-
if (identical(value, null)) {
60+
/// Sets a cookie. Setting a cookie to [null] deletes the cookie.
61+
void operator[]=(name, value) {
62+
if (value == null) {
7663
_document.cookie = "${_escape(name)}=;path=$cookiePath;expires=Thu, 01 Jan 1970 00:00:00 GMT";
7764
} else {
7865
if (value is String) {
79-
var cookieLength = (_document.cookie = "${_escape(name)}=${_escape(value)};path=$cookiePath").length + 1;
66+
var cookie = "${_escape(name)}=${_escape(value)};path=$cookiePath";
67+
_document.cookie = cookie;
68+
var cookieLength = cookie.length + 1;
8069

8170
// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
8271
// - 300 cookies
8372
// - 20 cookies per unique domain
8473
// - 4096 bytes per cookie
8574
if (cookieLength > 4096) {
8675
_exceptionHandler("Cookie '$name' possibly not set or overflowed because it was " +
87-
"too large ($cookieLength > 4096 bytes)!", null);
76+
"too large ($cookieLength > 4096 bytes)!", null);
8877
}
8978
}
9079
}
9180
}
9281

93-
get all => _updateLastCookies();
82+
Map<String, String> get all => _updateLastCookies();
9483
}
9584

96-
/**
97-
* Cookies service
98-
*/
85+
/// Handling of browser cookies
9986
@Injectable()
10087
class Cookies {
10188
BrowserCookies _browserCookies;
89+
10290
Cookies(this._browserCookies);
10391

104-
/**
105-
* Returns the value of given cookie key
106-
*/
107-
operator[](name) => this._browserCookies[name];
92+
/// Returns the value of given cookie key
93+
String operator[](name) => _browserCookies[name];
10894

109-
/**
110-
* Sets a value for given cookie key
111-
*/
112-
operator[]=(name, value) => this._browserCookies[name] = value;
95+
/// Sets a value for given cookie key
96+
void operator[]=(name, value) {
97+
_browserCookies[name] = value;
98+
}
11399

114-
/**
115-
* Remove given cookie
116-
*/
117-
remove(name) => this._browserCookies[name] = null;
100+
/// Remove given cookie
101+
void remove(name) {
102+
_browserCookies[name] = null;
103+
}
118104
}
119105

lib/directive/ng_events.dart

+59-71
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
part of angular.directive;
22

3-
// NOTE(deboer): onXX functions are now typed as 'var' instead of 'Getter'
4-
// to work-around https://code.google.com/p/dart/issues/detail?id=13519
5-
63
/**
74
* Allows you to specify custom behavior for DOM UI events such as mouse,
85
* keyboard and touch events.
@@ -128,82 +125,73 @@ part of angular.directive;
128125
@Decorator(selector: '[ng-touchmove]', map: const {'ng-touchmove': '&onTouchMove'})
129126
@Decorator(selector: '[ng-touchstart]', map: const {'ng-touchstart': '&onTouchStart'})
130127
@Decorator(selector: '[ng-transitionend]', map: const {'ng-transitionend': '&onTransitionEnd'})
131-
132128
class NgEvent {
133-
// Is it better to use a map of listeners or have 29 properties on this
134-
// object? One would pretty much only assign to one or two of those
135-
// properties. I'm opting for the map since it's less boilerplate code.
136-
var listeners = new HashMap();
137-
final dom.Element element;
138-
final Scope scope;
129+
// Is it better to use a map of listeners or have 29 properties on this object? One would pretty
130+
// much only assign to one or two of those properties. I'm opting for the map since it's less
131+
// boilerplate code.
132+
var listeners = new HashMap<int, BoundExpression>();
133+
final dom.Element _element;
134+
final Scope _scope;
139135

140-
NgEvent(this.element, this.scope);
136+
NgEvent(this._element, this._scope);
141137

142-
// NOTE: Do not use the element.on['some_event'].listen(...) syntax. Doing so
143-
// has two downsides:
144-
// - it loses the event typing
145-
// - some DOM events may have multiple platform-dependent event names
146-
// under the covers. The standard Stream getters you will get the
147-
// platform specific event name automatically but you're on your own if
148-
// you use the on[] syntax. This also applies to $dom_addEventListener.
149-
// Ref: http://api.dartlang.org/docs/releases/latest/dart_html/Events.html
150-
initListener(var stream, var handler) {
138+
void _initListener(stream, BoundExpression handler) {
151139
int key = stream.hashCode;
152140
if (!listeners.containsKey(key)) {
153141
listeners[key] = handler;
154142
stream.listen((event) => handler({r"$event": event}));
155143
}
156144
}
157145

158-
set onAbort(value) => initListener(element.onAbort, value);
159-
set onBeforeCopy(value) => initListener(element.onBeforeCopy, value);
160-
set onBeforeCut(value) => initListener(element.onBeforeCut, value);
161-
set onBeforePaste(value) => initListener(element.onBeforePaste, value);
162-
set onBlur(value) => initListener(element.onBlur, value);
163-
set onChange(value) => initListener(element.onChange, value);
164-
set onClick(value) => initListener(element.onClick, value);
165-
set onContextMenu(value) => initListener(element.onContextMenu, value);
166-
set onCopy(value) => initListener(element.onCopy, value);
167-
set onCut(value) => initListener(element.onCut, value);
168-
set onDoubleClick(value) => initListener(element.onDoubleClick, value);
169-
set onDrag(value) => initListener(element.onDrag, value);
170-
set onDragEnd(value) => initListener(element.onDragEnd, value);
171-
set onDragEnter(value) => initListener(element.onDragEnter, value);
172-
set onDragLeave(value) => initListener(element.onDragLeave, value);
173-
set onDragOver(value) => initListener(element.onDragOver, value);
174-
set onDragStart(value) => initListener(element.onDragStart, value);
175-
set onDrop(value) => initListener(element.onDrop, value);
176-
set onError(value) => initListener(element.onError, value);
177-
set onFocus(value) => initListener(element.onFocus, value);
178-
set onFullscreenChange(value) => initListener(element.onFullscreenChange, value);
179-
set onFullscreenError(value) => initListener(element.onFullscreenError, value);
180-
set onInput(value) => initListener(element.onInput, value);
181-
set onInvalid(value) => initListener(element.onInvalid, value);
182-
set onKeyDown(value) => initListener(element.onKeyDown, value);
183-
set onKeyPress(value) => initListener(element.onKeyPress, value);
184-
set onKeyUp(value) => initListener(element.onKeyUp, value);
185-
set onLoad(value) => initListener(element.onLoad, value);
186-
set onMouseDown(value) => initListener(element.onMouseDown, value);
187-
set onMouseEnter(value) => initListener(element.onMouseEnter, value);
188-
set onMouseLeave(value) => initListener(element.onMouseLeave, value);
189-
set onMouseMove(value) => initListener(element.onMouseMove, value);
190-
set onMouseOut(value) => initListener(element.onMouseOut, value);
191-
set onMouseOver(value) => initListener(element.onMouseOver, value);
192-
set onMouseUp(value) => initListener(element.onMouseUp, value);
193-
set onMouseWheel(value) => initListener(element.onMouseWheel, value);
194-
set onPaste(value) => initListener(element.onPaste, value);
195-
set onReset(value) => initListener(element.onReset, value);
196-
set onScroll(value) => initListener(element.onScroll, value);
197-
set onSearch(value) => initListener(element.onSearch, value);
198-
set onSelect(value) => initListener(element.onSelect, value);
199-
set onSelectStart(value) => initListener(element.onSelectStart, value);
200-
// set onSpeechChange(value) => initListener(element.onSpeechChange, value);
201-
set onSubmit(value) => initListener(element.onSubmit, value);
202-
set onTouchCancel(value) => initListener(element.onTouchCancel, value);
203-
set onTouchEnd(value) => initListener(element.onTouchEnd, value);
204-
set onTouchEnter(value) => initListener(element.onTouchEnter, value);
205-
set onTouchLeave(value) => initListener(element.onTouchLeave, value);
206-
set onTouchMove(value) => initListener(element.onTouchMove, value);
207-
set onTouchStart(value) => initListener(element.onTouchStart, value);
208-
set onTransitionEnd(value) => initListener(element.onTransitionEnd, value);
146+
void set onAbort(value) => _initListener(_element.onAbort, value);
147+
void set onBeforeCopy(value) => _initListener(_element.onBeforeCopy, value);
148+
void set onBeforeCut(value) => _initListener(_element.onBeforeCut, value);
149+
void set onBeforePaste(value) => _initListener(_element.onBeforePaste, value);
150+
void set onBlur(value) => _initListener(_element.onBlur, value);
151+
void set onChange(value) => _initListener(_element.onChange, value);
152+
void set onClick(value) => _initListener(_element.onClick, value);
153+
void set onContextMenu(value) => _initListener(_element.onContextMenu, value);
154+
void set onCopy(value) => _initListener(_element.onCopy, value);
155+
void set onCut(value) => _initListener(_element.onCut, value);
156+
void set onDoubleClick(value) => _initListener(_element.onDoubleClick, value);
157+
void set onDrag(value) => _initListener(_element.onDrag, value);
158+
void set onDragEnd(value) => _initListener(_element.onDragEnd, value);
159+
void set onDragEnter(value) => _initListener(_element.onDragEnter, value);
160+
void set onDragLeave(value) => _initListener(_element.onDragLeave, value);
161+
void set onDragOver(value) => _initListener(_element.onDragOver, value);
162+
void set onDragStart(value) => _initListener(_element.onDragStart, value);
163+
void set onDrop(value) => _initListener(_element.onDrop, value);
164+
void set onError(value) => _initListener(_element.onError, value);
165+
void set onFocus(value) => _initListener(_element.onFocus, value);
166+
void set onFullscreenChange(value) => _initListener(_element.onFullscreenChange, value);
167+
void set onFullscreenError(value) => _initListener(_element.onFullscreenError, value);
168+
void set onInput(value) => _initListener(_element.onInput, value);
169+
void set onInvalid(value) => _initListener(_element.onInvalid, value);
170+
void set onKeyDown(value) => _initListener(_element.onKeyDown, value);
171+
void set onKeyPress(value) => _initListener(_element.onKeyPress, value);
172+
void set onKeyUp(value) => _initListener(_element.onKeyUp, value);
173+
void set onLoad(value) => _initListener(_element.onLoad, value);
174+
void set onMouseDown(value) => _initListener(_element.onMouseDown, value);
175+
void set onMouseEnter(value) => _initListener(_element.onMouseEnter, value);
176+
void set onMouseLeave(value) => _initListener(_element.onMouseLeave, value);
177+
void set onMouseMove(value) => _initListener(_element.onMouseMove, value);
178+
void set onMouseOut(value) => _initListener(_element.onMouseOut, value);
179+
void set onMouseOver(value) => _initListener(_element.onMouseOver, value);
180+
void set onMouseUp(value) => _initListener(_element.onMouseUp, value);
181+
void set onMouseWheel(value) => _initListener(_element.onMouseWheel, value);
182+
void set onPaste(value) => _initListener(_element.onPaste, value);
183+
void set onReset(value) => _initListener(_element.onReset, value);
184+
void set onScroll(value) => _initListener(_element.onScroll, value);
185+
void set onSearch(value) => _initListener(_element.onSearch, value);
186+
void set onSelect(value) => _initListener(_element.onSelect, value);
187+
void set onSelectStart(value) => _initListener(_element.onSelectStart, value);
188+
// void set onSpeechChange(value) => initListener(element.onSpeechChange, value);
189+
void set onSubmit(value) => _initListener(_element.onSubmit, value);
190+
void set onTouchCancel(value) => _initListener(_element.onTouchCancel, value);
191+
void set onTouchEnd(value) => _initListener(_element.onTouchEnd, value);
192+
void set onTouchEnter(value) => _initListener(_element.onTouchEnter, value);
193+
void set onTouchLeave(value) => _initListener(_element.onTouchLeave, value);
194+
void set onTouchMove(value) => _initListener(_element.onTouchMove, value);
195+
void set onTouchStart(value) => _initListener(_element.onTouchStart, value);
196+
void set onTransitionEnd(value) => _initListener(_element.onTransitionEnd, value);
209197
}

0 commit comments

Comments
 (0)