diff --git a/test/helpers/privateMocks.js b/test/helpers/privateMocks.js
index 637f19ebf97c..ae57f116cc0e 100644
--- a/test/helpers/privateMocks.js
+++ b/test/helpers/privateMocks.js
@@ -40,9 +40,8 @@ function browserSupportsCssAnimations() {
return true;
}
-function createMockStyleSheet(doc, wind) {
+function createMockStyleSheet(doc, prefix) {
doc = doc ? doc[0] : document;
- wind = wind || window;
var node = doc.createElement('style');
var head = doc.getElementsByTagName('head')[0];
@@ -63,6 +62,18 @@ function createMockStyleSheet(doc, wind) {
}
},
+ addPossiblyPrefixedRule: function(selector, styles) {
+ if (prefix) {
+ var prefixedStyles = styles.split(/\s*;\s*/g).map(function(style) {
+ return !style ? '' : prefix + style;
+ }).join('; ');
+
+ this.addRule(selector, prefixedStyles);
+ }
+
+ this.addRule(selector, styles);
+ },
+
destroy: function() {
head.removeChild(node);
}
diff --git a/test/helpers/privateMocksSpec.js b/test/helpers/privateMocksSpec.js
index 495dcb60c6ef..c584b1d33c39 100644
--- a/test/helpers/privateMocksSpec.js
+++ b/test/helpers/privateMocksSpec.js
@@ -211,7 +211,7 @@ describe('private mocks', function() {
var doc = $document[0];
var count = doc.styleSheets.length;
- var stylesheet = createMockStyleSheet($document, $window);
+ var stylesheet = createMockStyleSheet($document);
var elm;
runs(function() {
expect(doc.styleSheets.length).toBe(count + 1);
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index 884f6c8846c4..d79d55a0774c 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -230,6 +230,9 @@ describe('$compile', function() {
describe('svg namespace transcludes', function() {
+ var ua = window.navigator.userAgent;
+ var isEdge = /Edge/.test(ua);
+
// this method assumes some sort of sized SVG element is being inspected.
function assertIsValidSvgCircle(elem) {
expect(isUnknownElement(elem)).toBe(false);
@@ -300,17 +303,19 @@ describe('$compile', function() {
}));
// NOTE: This test may be redundant.
- it('should handle custom svg containers that transclude to foreignObject' +
- ' that transclude to custom svg containers that transclude to custom elements', inject(function() {
- element = jqLite('
' +
- '' +
- '
');
- $compile(element.contents())($rootScope);
- document.body.appendChild(element[0]);
-
- var circle = element.find('circle');
- assertIsValidSvgCircle(circle[0]);
- }));
+ if (!isEdge) {
+ it('should handle custom svg containers that transclude to foreignObject' +
+ ' that transclude to custom svg containers that transclude to custom elements', inject(function() {
+ element = jqLite('
' +
+ '' +
+ '
');
+ $compile(element.contents())($rootScope);
+ document.body.appendChild(element[0]);
+
+ var circle = element.find('circle');
+ assertIsValidSvgCircle(circle[0]);
+ }));
+ }
}
it('should handle directives with templates that manually add the transclude further down', inject(function() {
diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js
index 58689c0eea5f..b8ba4ed924d2 100644
--- a/test/ng/directive/inputSpec.js
+++ b/test/ng/directive/inputSpec.js
@@ -1196,7 +1196,7 @@ describe('input', function() {
it('should validate if max is empty', function() {
$rootScope.maxVal = undefined;
- $rootScope.value = new Date(9999, 11, 31, 23, 59, 59);
+ $rootScope.value = new Date(3000, 11, 31, 23, 59, 59);
$rootScope.$digest();
expect($rootScope.form.alias.$error.max).toBeFalsy();
diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js
index 4523718b64f0..e91939ca3194 100644
--- a/test/ng/directive/ngRepeatSpec.js
+++ b/test/ng/directive/ngRepeatSpec.js
@@ -1491,11 +1491,11 @@ describe('ngRepeat animations', function() {
}));
it('should not change the position of the block that is being animated away via a leave animation',
- inject(function($compile, $rootScope, $animate, $document, $window, $sniffer, $timeout) {
+ inject(function($compile, $rootScope, $animate, $document, $sniffer, $timeout) {
if (!$sniffer.transitions) return;
var item;
- var ss = createMockStyleSheet($document, $window);
+ var ss = createMockStyleSheet($document);
try {
diff --git a/test/ng/snifferSpec.js b/test/ng/snifferSpec.js
index c16d4802d966..b1fafceff36d 100644
--- a/test/ng/snifferSpec.js
+++ b/test/ng/snifferSpec.js
@@ -88,7 +88,9 @@ describe('$sniffer', function() {
inject(function($sniffer, $window) {
var expectedPrefix;
var ua = $window.navigator.userAgent.toLowerCase();
- if (/chrome/i.test(ua) || /safari/i.test(ua) || /webkit/i.test(ua)) {
+ if (/edge/i.test(ua)) {
+ expectedPrefix = 'Ms';
+ } else if (/chrome/i.test(ua) || /safari/i.test(ua) || /webkit/i.test(ua)) {
expectedPrefix = 'Webkit';
} else if (/firefox/i.test(ua)) {
expectedPrefix = 'Moz';
diff --git a/test/ngAnimate/animateCssDriverSpec.js b/test/ngAnimate/animateCssDriverSpec.js
index 97567e4c053e..abc4eefa7a89 100644
--- a/test/ngAnimate/animateCssDriverSpec.js
+++ b/test/ngAnimate/animateCssDriverSpec.js
@@ -69,11 +69,11 @@ describe("ngAnimate $$animateCssDriver", function() {
element = jqLite('');
- return function($$animateCssDriver, $document, $window) {
+ return function($$animateCssDriver, $document) {
driver = function(details, cb) {
return $$animateCssDriver(details, cb || noop);
};
- ss = createMockStyleSheet($document, $window);
+ ss = createMockStyleSheet($document);
};
}));
diff --git a/test/ngAnimate/animateCssSpec.js b/test/ngAnimate/animateCssSpec.js
index e43dd89a912c..c8939d60252f 100644
--- a/test/ngAnimate/animateCssSpec.js
+++ b/test/ngAnimate/animateCssSpec.js
@@ -12,6 +12,13 @@ describe("ngAnimate $animateCss", function() {
: expect(className).not.toMatch(regex);
}
+ function getPossiblyPrefixedStyleValue(element, styleProp) {
+ var value = element.css(prefix + styleProp);
+ if (isUndefined(value)) value = element.css(styleProp);
+
+ return value;
+ }
+
function keyframeProgress(element, duration, delay) {
browserTrigger(element, 'animationend',
{ timeStamp: Date.now() + ((delay || 1) * 1000), elapsedTime: duration });
@@ -28,9 +35,10 @@ describe("ngAnimate $animateCss", function() {
var ss, prefix, triggerAnimationStartFrame;
beforeEach(module(function() {
- return function($document, $window, $sniffer, $$rAF, $animate) {
+ return function($document, $sniffer, $$rAF, $animate) {
prefix = '-' + $sniffer.vendorPrefix.toLowerCase() + '-';
- ss = createMockStyleSheet($document, $window);
+ ss = createMockStyleSheet($document, prefix);
+
$animate.enabled(true);
triggerAnimationStartFrame = function() {
$$rAF.flush();
@@ -325,7 +333,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
runner.pause();
- expect(element.css(prefix + 'animation-play-state')).toEqual('paused');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-play-state')).toEqual('paused');
runner.resume();
expect(element.attr('style')).toBeFalsy();
}));
@@ -346,7 +354,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
runner.pause();
- expect(element.css(prefix + 'animation-play-state')).toEqual('paused');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-play-state')).toEqual('paused');
runner.end();
expect(element.attr('style')).toBeFalsy();
}));
@@ -784,8 +792,8 @@ describe("ngAnimate $animateCss", function() {
jqLite($document[0].body).append($rootElement);
- ss.addRule('.ng-enter-stagger', prefix + 'animation-delay:0.2s');
- ss.addRule('.ng-enter', prefix + 'animation:my_animation 2s;');
+ ss.addPossiblyPrefixedRule('.ng-enter-stagger', 'animation-delay:0.2s');
+ ss.addPossiblyPrefixedRule('.ng-enter', 'animation:my_animation 2s;');
var i, element, elements = [];
for (i = 0; i < 5; i++) {
@@ -803,7 +811,7 @@ describe("ngAnimate $animateCss", function() {
if (i === 0) { // the first element is always run right away
expect(element.attr('style')).toBeFalsy();
} else {
- expect(element.css(prefix + 'animation-play-state')).toBe('paused');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-play-state')).toBe('paused');
}
}
}));
@@ -879,7 +887,7 @@ describe("ngAnimate $animateCss", function() {
jqLite($document[0].body).append($rootElement);
ss.addRule('.ng-enter-stagger', 'transition-delay:0.2s');
- ss.addRule('.transition-animation', prefix + 'animation:2s 5s my_animation;');
+ ss.addPossiblyPrefixedRule('.transition-animation', 'animation: 2s 5s my_animation;');
for (var i = 0; i < 5; i++) {
var elm = jqLite('');
@@ -898,11 +906,11 @@ describe("ngAnimate $animateCss", function() {
jqLite($document[0].body).append($rootElement);
- ss.addRule('.ng-enter-stagger', 'transition-delay:0.5s;' +
- prefix + 'animation-delay:1s');
+ ss.addPossiblyPrefixedRule('.ng-enter-stagger', 'transition-delay: 0.5s; ' +
+ 'animation-delay: 1s');
- ss.addRule('.ng-enter', 'transition:10s linear all;' +
- prefix + 'animation:my_animation 20s');
+ ss.addPossiblyPrefixedRule('.ng-enter', 'transition: 10s linear all; ' +
+ 'animation: 20s my_animation');
var i, elm, elements = [];
for (i = 0; i < 5; i++) {
@@ -1258,14 +1266,14 @@ describe("ngAnimate $animateCss", function() {
// At this point, the animation should still be running (closing timeout is 7500ms ... duration * 1.5 + delay => 7.5)
$timeout.flush(7000);
- expect(element.css(prefix + 'transition-delay')).toBe('3s');
- expect(element.css(prefix + 'transition-duration')).toBe('3s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).toBe('3s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).toBe('3s');
// Let's flush the remaining amount of time for the timeout timer to kick in
$timeout.flush(500);
- expect(element.css(prefix + 'transition-duration')).toBeOneOf('', '0s');
- expect(element.css(prefix + 'transition-delay')).toBeOneOf('', '0s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).toBeOneOf('', '0s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).toBeOneOf('', '0s');
}));
it("should ignore a boolean options.delay value for the closing timeout",
@@ -1291,14 +1299,14 @@ describe("ngAnimate $animateCss", function() {
// At this point, the animation should still be running (closing timeout is 4500ms ... duration * 1.5 => 4.5)
$timeout.flush(4000);
- expect(element.css(prefix + 'transition-delay')).toBeOneOf('initial', '0s');
- expect(element.css(prefix + 'transition-duration')).toBe('3s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).toBeOneOf('initial', '0s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).toBe('3s');
// Let's flush the remaining amount of time for the timeout timer to kick in
$timeout.flush(500);
- expect(element.css(prefix + 'transition-duration')).toBeOneOf('', '0s');
- expect(element.css(prefix + 'transition-delay')).toBeOneOf('', '0s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).toBeOneOf('', '0s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).toBeOneOf('', '0s');
}));
});
@@ -2104,7 +2112,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-duration')).toEqual('5s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-duration')).toEqual('5s');
}));
it("should remove all inline keyframe styling when an animation completes if a custom duration was applied",
@@ -2145,7 +2153,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toEqual('5s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('5s');
browserTrigger(element, 'animationend',
{ timeStamp: Date.now() + 5000, elapsedTime: 1.5 });
@@ -2299,7 +2307,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toEqual('400s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('400s');
expect(element.attr('style')).not.toContain('transition-delay');
}));
@@ -2323,7 +2331,7 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toEqual('10s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('10s');
expect(element.css('transition-delay')).toEqual('10s');
}));
@@ -2363,7 +2371,7 @@ describe("ngAnimate $animateCss", function() {
var assertionsRun = false;
classSpy = function() {
assertionsRun = true;
- expect(element.css(prefix + 'animation-delay')).toEqual('2s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('2s');
expect(element.css('transition-delay')).toEqual('2s');
expect(element).not.toHaveClass('superman');
};
@@ -2397,8 +2405,8 @@ describe("ngAnimate $animateCss", function() {
it("should consider a negative value when delay:true is used with a keyframe animation",
inject(function($animateCss, $rootElement) {
- ss.addRule('.ng-enter', prefix + 'animation:2s keyframe_animation; ' +
- prefix + 'animation-delay: -1s;');
+ ss.addPossiblyPrefixedRule('.ng-enter', 'animation: 2s keyframe_animation; ' +
+ 'animation-delay: -1s;');
var options = {
delay: true,
@@ -2411,7 +2419,7 @@ describe("ngAnimate $animateCss", function() {
animator.start();
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toContain('-1s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toContain('-1s');
}));
they("should consider a negative value when a negative option delay is provided for a $prop animation", {
@@ -2421,17 +2429,17 @@ describe("ngAnimate $animateCss", function() {
css: 'transition:2s linear all'
};
},
- 'keyframe': function(prefix) {
+ 'keyframe': function() {
return {
- prop: prefix + 'animation-delay',
- css: prefix + 'animation:2s keyframe_animation'
+ prop: 'animation-delay',
+ css: 'animation: 2s keyframe_animation'
};
}
}, function(testDetailsFactory) {
inject(function($animateCss, $rootElement) {
var testDetails = testDetailsFactory(prefix);
- ss.addRule('.ng-enter', testDetails.css);
+ ss.addPossiblyPrefixedRule('.ng-enter', testDetails.css);
var options = {
delay: -2,
event: 'enter',
@@ -2443,7 +2451,7 @@ describe("ngAnimate $animateCss", function() {
animator.start();
triggerAnimationStartFrame();
- expect(element.css(testDetails.prop)).toContain('-2s');
+ expect(getPossiblyPrefixedStyleValue(element, testDetails.prop)).toContain('-2s');
});
});
@@ -2454,18 +2462,18 @@ describe("ngAnimate $animateCss", function() {
css: 'transition:5s linear all; transition-delay: -2s'
};
},
- 'animation': function(prefix) {
+ 'animation': function() {
return {
event: 'animationend',
- css: prefix + 'animation:5s keyframe_animation; ' + prefix + 'animation-delay: -2s;'
+ css: 'animation: 5s keyframe_animation; animation-delay: -2s;'
};
}
}, function(testDetailsFactory) {
inject(function($animateCss, $rootElement) {
- var testDetails = testDetailsFactory(prefix);
+ var testDetails = testDetailsFactory();
var event = testDetails.event;
- ss.addRule('.ng-enter', testDetails.css);
+ ss.addPossiblyPrefixedRule('.ng-enter', testDetails.css);
var options = { event: 'enter', structural: true };
var animator = $animateCss(element, options);
@@ -2571,15 +2579,15 @@ describe("ngAnimate $animateCss", function() {
$animateCss(element, options).start();
triggerAnimationStartFrame();
- expect(element.css(prefix + 'transition-delay')).not.toEqual('4s');
- expect(element.css(prefix + 'transition-duration')).not.toEqual('6s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).not.toEqual('4s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).not.toEqual('6s');
options.to = { color: 'brown' };
$animateCss(element, options).start();
triggerAnimationStartFrame();
- expect(element.css(prefix + 'transition-delay')).toEqual('4s');
- expect(element.css(prefix + 'transition-duration')).toEqual('6s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-delay')).toEqual('4s');
+ expect(getPossiblyPrefixedStyleValue(element, 'transition-duration')).toEqual('6s');
}));
});
@@ -2652,9 +2660,9 @@ describe("ngAnimate $animateCss", function() {
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toEqual('50s');
- expect(element.css(prefix + 'animation-duration')).toEqual('5.5s');
- expect(element.css(prefix + 'animation-name')).toEqual('my_animation');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('50s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-duration')).toEqual('5.5s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-name')).toEqual('my_animation');
}));
it("should be able to execute the animation if it is the only provided value",
@@ -2669,9 +2677,9 @@ describe("ngAnimate $animateCss", function() {
animator.start();
triggerAnimationStartFrame();
- expect(element.css(prefix + 'animation-delay')).toEqual('10s');
- expect(element.css(prefix + 'animation-duration')).toEqual('5.5s');
- expect(element.css(prefix + 'animation-name')).toEqual('my_animation');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-delay')).toEqual('10s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-duration')).toEqual('5.5s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-name')).toEqual('my_animation');
}));
});
@@ -2964,7 +2972,7 @@ describe("ngAnimate $animateCss", function() {
expect(element.css('transition-duration')).toMatch('10s');
- expect(element.css(prefix + 'animation-duration')).toEqual('10s');
+ expect(getPossiblyPrefixedStyleValue(element, 'animation-duration')).toEqual('10s');
}));
});
@@ -3004,7 +3012,7 @@ describe("ngAnimate $animateCss", function() {
inject(function($animateCss) {
ss.addRule('.red', 'transition: 1s linear all;');
- ss.addRule('.blue', prefix + 'animation:my_keyframe 1s;');
+ ss.addPossiblyPrefixedRule('.blue', 'animation: 1s my_keyframe;');
var easing = 'ease-out';
var animator = $animateCss(element, { addClass: 'red blue', easing: easing });
animator.start();
diff --git a/test/ngAnimate/integrationSpec.js b/test/ngAnimate/integrationSpec.js
index 5c67897c8492..e72593d1cbb2 100644
--- a/test/ngAnimate/integrationSpec.js
+++ b/test/ngAnimate/integrationSpec.js
@@ -7,10 +7,10 @@ describe('ngAnimate integration tests', function() {
var element, html, ss;
beforeEach(module(function() {
- return function($rootElement, $document, $window, $animate) {
+ return function($rootElement, $document, $animate) {
$animate.enabled(true);
- ss = createMockStyleSheet($document, $window);
+ ss = createMockStyleSheet($document);
var body = jqLite($document[0].body);
html = function(element) {
diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js
index 434394143e24..818d33e3003a 100644
--- a/test/ngMock/angular-mocksSpec.js
+++ b/test/ngMock/angular-mocksSpec.js
@@ -2046,8 +2046,8 @@ describe('ngMockE2E', function() {
}
});
- return function($animate, $rootElement, $document, $rootScope, $window) {
- ss = createMockStyleSheet($document, $window);
+ return function($animate, $rootElement, $document, $rootScope) {
+ ss = createMockStyleSheet($document);
element = angular.element('');
$rootElement.append(element);
diff --git a/test/ngSanitize/sanitizeSpec.js b/test/ngSanitize/sanitizeSpec.js
index b5c9d33bc0b2..6455ba94d6ee 100644
--- a/test/ngSanitize/sanitizeSpec.js
+++ b/test/ngSanitize/sanitizeSpec.js
@@ -1,6 +1,8 @@
'use strict';
describe('HTML', function() {
+ var ua = window.navigator.userAgent;
+ var isChrome = /Chrome/.test(ua) && !/Edge/.test(ua);
var expectHTML;
@@ -222,7 +224,7 @@ describe('HTML', function() {
.toEqual('');
});
- if (/Chrome/.test(window.navigator.userAgent)) {
+ if (isChrome) {
it('should prevent mXSS attacks', function() {
expectHTML('CLICKME').toBe('CLICKME');
});
@@ -245,7 +247,8 @@ describe('HTML', function() {
expectHTML('')
.toBeOneOf('',
'',
- '');
+ '',
+ '');
});
it('should not ignore white-listed svg camelCased attributes', function() {
@@ -283,6 +286,7 @@ describe('HTML', function() {
it('should not accept SVG animation tags', function() {
expectHTML('')
.toBeOneOf('',
+ '',
'');
expectHTML('