ui5-test-runner 1.1.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +32 -188
  2. package/index.js +47 -16
  3. package/package.json +28 -10
  4. package/src/add-test-pages.js +35 -0
  5. package/src/add-test-pages.spec.js +95 -0
  6. package/src/browser.spec.js +724 -0
  7. package/src/browsers.js +220 -59
  8. package/src/capabilities/index.js +194 -0
  9. package/src/capabilities/tests/basic/iframe.html +8 -0
  10. package/src/capabilities/tests/basic/index.html +12 -0
  11. package/src/capabilities/tests/basic/index.js +20 -0
  12. package/src/capabilities/tests/basic/ui5.html +24 -0
  13. package/src/capabilities/tests/dynamic-include/index.js +21 -0
  14. package/src/capabilities/tests/dynamic-include/mix.html +11 -0
  15. package/src/capabilities/tests/dynamic-include/one.html +11 -0
  16. package/src/capabilities/tests/dynamic-include/post.js +3 -0
  17. package/src/capabilities/tests/dynamic-include/test.js +1 -0
  18. package/src/capabilities/tests/dynamic-include/two.html +11 -0
  19. package/src/capabilities/tests/index.js +16 -0
  20. package/src/capabilities/tests/local-storage/index.html +16 -0
  21. package/src/capabilities/tests/local-storage/index.js +21 -0
  22. package/src/capabilities/tests/screenshot/index.html +13 -0
  23. package/src/capabilities/tests/screenshot/index.js +18 -0
  24. package/src/capabilities/tests/scripts/index.js +50 -0
  25. package/src/capabilities/tests/scripts/qunit.html +22 -0
  26. package/src/capabilities/tests/scripts/testsuite.html +10 -0
  27. package/src/capabilities/tests/scripts/testsuite.js +8 -0
  28. package/src/capabilities/tests/timeout/index.html +21 -0
  29. package/src/capabilities/tests/timeout/index.js +19 -0
  30. package/src/capabilities/tests/traces/index.html +18 -0
  31. package/src/capabilities/tests/traces/index.js +81 -0
  32. package/src/cors.js +1 -1
  33. package/src/cors.spec.js +41 -0
  34. package/src/coverage.js +30 -18
  35. package/src/coverage.spec.js +79 -0
  36. package/src/csv-reader.js +36 -0
  37. package/src/csv-reader.spec.js +42 -0
  38. package/src/csv-writer.js +52 -0
  39. package/src/csv-writer.spec.js +77 -0
  40. package/src/defaults/browser.js +144 -0
  41. package/src/defaults/jsdom/compatibility.js +95 -0
  42. package/src/defaults/jsdom/debug.js +23 -0
  43. package/src/defaults/jsdom/resource-loader.js +43 -0
  44. package/src/defaults/jsdom/sap.ui.test.matchers.visible.js +39 -0
  45. package/src/defaults/jsdom.js +64 -0
  46. package/src/defaults/junit-xml-report.js +64 -0
  47. package/src/defaults/puppeteer.js +111 -0
  48. package/src/defaults/report/common.js +38 -0
  49. package/src/defaults/report/default.html +84 -0
  50. package/src/defaults/report/main.js +44 -0
  51. package/src/defaults/report/progress.js +49 -0
  52. package/src/defaults/report/styles.css +66 -0
  53. package/src/defaults/report.js +69 -0
  54. package/src/defaults/selenium-webdriver/chrome.js +38 -0
  55. package/src/defaults/selenium-webdriver/edge.js +25 -0
  56. package/src/defaults/selenium-webdriver/firefox.js +31 -0
  57. package/src/defaults/selenium-webdriver.js +138 -0
  58. package/src/endpoints.js +70 -124
  59. package/src/error.js +52 -0
  60. package/src/error.spec.js +17 -0
  61. package/src/get-job-progress.js +69 -0
  62. package/src/get-job-progress.spec.js +175 -0
  63. package/src/inject/post.js +96 -0
  64. package/src/inject/post.spec.js +147 -0
  65. package/src/inject/qunit-hooks.js +6 -21
  66. package/src/inject/qunit-intercept.js +30 -0
  67. package/src/inject/qunit-redirect.js +15 -7
  68. package/src/job-mode.js +45 -0
  69. package/src/job.js +254 -108
  70. package/src/job.spec.js +413 -0
  71. package/src/npm.js +73 -0
  72. package/src/npm.spec.js +98 -0
  73. package/src/options.js +73 -0
  74. package/src/options.spec.js +125 -0
  75. package/src/output.js +450 -131
  76. package/src/qunit-hooks.js +116 -0
  77. package/src/qunit-hooks.spec.js +687 -0
  78. package/src/report.js +47 -0
  79. package/src/reserve.js +3 -4
  80. package/src/simulate.spec.js +466 -0
  81. package/src/symbols.js +8 -0
  82. package/src/tests.js +127 -84
  83. package/src/timeout.spec.js +39 -0
  84. package/src/tools.js +111 -4
  85. package/src/tools.spec.js +90 -0
  86. package/src/ui5.js +3 -3
  87. package/src/unhandled.js +6 -6
  88. package/src/unhandled.spec.js +63 -0
  89. package/defaults/chromium.js +0 -62
  90. package/src/progress.html +0 -71
  91. package/src/proxies.js +0 -8
  92. package/src/report.html +0 -202
  93. /package/{defaults → src/defaults}/nyc.json +0 -0
@@ -0,0 +1,147 @@
1
+ class UI5Object {}
2
+ global.window = {
3
+ sap: {
4
+ ui: {
5
+ base: {
6
+ Object: UI5Object
7
+ }
8
+ }
9
+ }
10
+ }
11
+
12
+ require('./post')
13
+
14
+ describe('src/inject/post', () => {
15
+ describe('stringify', () => {
16
+ const stringify = window['ui5-test-runner/stringify']
17
+
18
+ describe('simple values', () => {
19
+ const simpleValues = [
20
+ null,
21
+ '',
22
+ 'Hello World !',
23
+ 0,
24
+ 1,
25
+ false,
26
+ true,
27
+ [],
28
+ [1, 2],
29
+ { a: 'a' },
30
+ { a: 'a', b: { b: 'b' } },
31
+ [{ a: 'a' }, { a: 'a', b: { b: 'b' } }]
32
+ ]
33
+
34
+ simpleValues.forEach(simpleValue => {
35
+ it(JSON.stringify(simpleValue), () => {
36
+ expect(stringify(simpleValue)).toBe(JSON.stringify(simpleValue))
37
+ })
38
+ })
39
+ })
40
+
41
+ describe('UI5 objects', () => {
42
+ it('reduces UI5 objects to their simplest form (no ID)', () => {
43
+ const obj = new UI5Object()
44
+ obj.getMetadata = () => ({
45
+ getName: () => 'sap.m.Button'
46
+ })
47
+ expect(JSON.parse(stringify(obj))).toStrictEqual({
48
+ 'ui5:class': 'sap.m.Button'
49
+ })
50
+ })
51
+
52
+ it('reduces UI5 objects to their simplest form (with ID)', () => {
53
+ const obj = new UI5Object()
54
+ obj.getId = () => 'test'
55
+ obj.getMetadata = () => ({
56
+ getName: () => 'sap.m.Button'
57
+ })
58
+ expect(JSON.parse(stringify(obj))).toStrictEqual({
59
+ 'ui5:id': 'test',
60
+ 'ui5:class': 'sap.m.Button'
61
+ })
62
+ })
63
+
64
+ it('works on a complex object', () => {
65
+ const obj = new UI5Object()
66
+ obj.getId = () => 'test'
67
+ obj.getMetadata = () => ({
68
+ getName: () => 'sap.m.Button'
69
+ })
70
+ expect(JSON.parse(stringify({
71
+ complex: obj
72
+ }))).toStrictEqual({
73
+ complex: {
74
+ 'ui5:id': 'test',
75
+ 'ui5:class': 'sap.m.Button'
76
+ }
77
+ })
78
+ })
79
+ })
80
+
81
+ describe('circular references', () => {
82
+ it('converts simple circular reference (object)', () => {
83
+ const a = { a: 'a' }
84
+ const b = { b: 'b' }
85
+ a.b = b
86
+ b.a = a
87
+ expect(JSON.parse(stringify(a))).toStrictEqual({
88
+ 'circular:id': 0,
89
+ a: 'a',
90
+ b: {
91
+ b: 'b',
92
+ a: {
93
+ 'circular:ref': 0
94
+ }
95
+ }
96
+ })
97
+ })
98
+
99
+ it('converts deep circular reference', () => {
100
+ const a = {
101
+ a: 'a',
102
+ b: {
103
+ b: 'b',
104
+ c: ['c'],
105
+ d: {
106
+ d: 'd'
107
+ }
108
+ }
109
+ }
110
+ a.b.c.push(a.b)
111
+ a.b.d.a = a
112
+ expect(JSON.parse(stringify(a))).toStrictEqual({
113
+ 'circular:id': 0,
114
+ a: 'a',
115
+ b: {
116
+ 'circular:id': 1,
117
+ b: 'b',
118
+ c: ['c', { 'circular:ref': 1 }],
119
+ d: {
120
+ d: 'd',
121
+ a: {
122
+ 'circular:ref': 0
123
+ }
124
+ }
125
+ }
126
+ })
127
+ })
128
+
129
+ it('converts simple circular reference (array)', () => {
130
+ const a = ['a']
131
+ const b = ['b']
132
+ a.push(b)
133
+ b.push(a)
134
+ expect(JSON.parse(stringify(a))).toStrictEqual({
135
+ 'circular:id': 0,
136
+ 'circular:array': [
137
+ 'a',
138
+ [
139
+ 'b',
140
+ { 'circular:ref': 0 }
141
+ ]
142
+ ]
143
+ })
144
+ })
145
+ })
146
+ })
147
+ })
@@ -7,22 +7,7 @@
7
7
  }
8
8
  window['ui5-test-runner/qunit-hooks'] = true
9
9
 
10
- function post (url, data) {
11
- return new Promise(function (resolve, reject) {
12
- const xhr = new XMLHttpRequest()
13
- xhr.open('POST', '/_/' + url)
14
- xhr.send(JSON.stringify(data))
15
- xhr.onreadystatechange = function () {
16
- if (xhr.readyState === 4) {
17
- if (xhr.status === 200) {
18
- resolve(xhr.responseText)
19
- } else {
20
- reject(xhr.statusText)
21
- }
22
- }
23
- }
24
- })
25
- }
10
+ const post = window['ui5-test-runner/post']
26
11
 
27
12
  function isOpa () {
28
13
  try {
@@ -37,12 +22,12 @@
37
22
  return post('QUnit/begin', details)
38
23
  })
39
24
 
40
- QUnit.log(function (report) {
25
+ QUnit.testStart(function (details) {
26
+ return post('QUnit/testStart', details)
27
+ })
28
+
29
+ QUnit.log(function (log) {
41
30
  let ready = false
42
- const log = {
43
- testId: report.testId,
44
- runtime: report.runtime
45
- }
46
31
  post('QUnit/log', log)
47
32
  .then(undefined, function () {
48
33
  console.error('Failed to POST to QUnit/log (no timestamp)', log)
@@ -0,0 +1,30 @@
1
+ /* Injected QUnit hooks */
2
+ (function () {
3
+ 'use strict'
4
+
5
+ const callbacks = {}
6
+ const mock = new Proxy({}, {
7
+ get: function (instance, property) {
8
+ if (property !== 'version') {
9
+ return function (callback) {
10
+ callbacks[property] = callback
11
+ }
12
+ }
13
+ }
14
+ })
15
+
16
+ let QUnit = mock
17
+
18
+ Object.defineProperty(window, 'QUnit', {
19
+ get: function () {
20
+ return QUnit
21
+ },
22
+
23
+ set: function (value) {
24
+ QUnit = value
25
+ Object.keys(callbacks).forEach(property => {
26
+ QUnit[property](callbacks[property])
27
+ })
28
+ }
29
+ })
30
+ }())
@@ -1,25 +1,33 @@
1
1
  (function () {
2
2
  'use strict'
3
3
 
4
+ if (window['ui5-test-runner/qunit-redirect']) {
5
+ return // already installed
6
+ }
7
+ window['ui5-test-runner/qunit-redirect'] = true
8
+
4
9
  /* global suite */
5
10
 
11
+ const post = window['ui5-test-runner/post']
12
+
6
13
  const pages = []
7
14
 
8
15
  function jsUnitTestSuite () {}
9
16
 
10
17
  jsUnitTestSuite.prototype.addTestPage = function (url) {
11
- if (!url.startsWith('/')) {
12
- url = '/' + url
13
- }
14
18
  pages.push(url)
15
19
  }
16
20
 
17
21
  window.jsUnitTestSuite = jsUnitTestSuite
18
22
 
19
23
  window.addEventListener('load', function () {
20
- suite()
21
- const xhr = new XMLHttpRequest()
22
- xhr.open('POST', '/_/addTestPages')
23
- xhr.send(JSON.stringify(pages))
24
+ if (typeof suite === 'function') {
25
+ suite()
26
+ post('addTestPages', pages)
27
+ } else if (typeof QUnit === 'object') {
28
+ post('addTestPages', [location.toString()])
29
+ } else {
30
+ post('addTestPages', []) // No page
31
+ }
24
32
  })
25
33
  }())
@@ -0,0 +1,45 @@
1
+ const { UTRError } = require('./error')
2
+ const { $valueSources } = require('./symbols')
3
+
4
+ function check (job, allowed, forbidden) {
5
+ const valueSources = job[$valueSources]
6
+ const incompatible = Object.keys(valueSources).filter(option => {
7
+ const source = valueSources[option]
8
+ return source === 'cli' && !option.startsWith('debug') &&
9
+ (
10
+ (allowed && !allowed.includes(option)) ||
11
+ (forbidden && forbidden.includes(option))
12
+ )
13
+ })
14
+ if (incompatible.length) {
15
+ throw UTRError.MODE_INCOMPATIBLE_OPTION(incompatible.join(','))
16
+ }
17
+ }
18
+
19
+ function buildAndCheckMode (job) {
20
+ if (job.capabilities) {
21
+ check(job, [
22
+ 'capabilities',
23
+ 'cwd',
24
+ 'port',
25
+ 'logServer',
26
+ 'browser',
27
+ 'parallel',
28
+ 'reportDir',
29
+ 'pageTimeout',
30
+ 'browserCloseTimeout',
31
+ 'failFast',
32
+ 'keepAlive'
33
+ ])
34
+ return 'capabilities'
35
+ }
36
+ if (job.url && job.url.length) {
37
+ check(job, undefined, ['testsuite'])
38
+ return 'url'
39
+ }
40
+ return 'legacy'
41
+ }
42
+
43
+ module.exports = {
44
+ buildAndCheckMode
45
+ }