Repository: karma-runner/karma (js)

Issue:
`%X_UA_COMPATIBLE%` displayed in the runner web page in debug mode
The runner web page in debug mode displays an `%X_UA_COMPATIBLE%` text.

![image](https://user-images.githubusercontent.com/169818/138448785-e77a19c8-d968-48c9-8bc5-65b681be1016.png)


Pull request description:
fix(middleware): replace %X_UA_COMPATIBLE% marker anywhere in the file
Previously %X_UA_COMPATIBLE% marker was only replaced if it was located at the start of the line. The limitation looks pretty arbitrary and caused the marker not to be replaced in the custom debug.html file used by Angular CLI as the marker was not located at the start of the line (probably because the file was re-formatted). This commit changes the behavior to replace the marker anywhere within the file, not just at the start of the line and thus fixes the problem for Angular CLI and potentially other people using custom files.

Fixes #3711

Patch:
diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js
index c92ae21a..5f701e7e 100644
--- a/lib/middleware/karma.js
+++ b/lib/middleware/karma.js
@@ -45,7 +45,7 @@ function getQuery (urlStr) {
 function getXUACompatibleMetaElement (url) {
   const query = getQuery(url)
   if (query['x-ua-compatible']) {
-    return `\n<meta http-equiv="X-UA-Compatible" content="${query['x-ua-compatible']}"/>`
+    return `<meta http-equiv="X-UA-Compatible" content="${query['x-ua-compatible']}"/>`
   }
   return ''
 }
@@ -107,7 +107,7 @@ function createKarmaMiddleware (
       } else { // serve client.html
         return serveStaticFile('/client.html', requestedRangeHeader, response, (data) =>
           data
-            .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
+            .replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
             .replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url)))
       }
     }
@@ -226,7 +226,7 @@ function createKarmaMiddleware (
             .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n')
             .replace('%SCRIPT_URL_ARRAY%', () => 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n')
             .replace('%MAPPINGS%', () => 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n')
-            .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
+            .replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
         })
       })
     } else if (requestUrl === '/context.json') {
diff --git a/static/client.html b/static/client.html
index 4e069e1e..73fb856a 100644
--- a/static/client.html
+++ b/static/client.html
@@ -5,7 +5,7 @@ It contains socket.io and all the communication logic.
 -->
 <html>
 <head>
-%X_UA_COMPATIBLE%
+  %X_UA_COMPATIBLE%
   <title>Karma</title>
   <link href="favicon.ico" rel="icon" type="image/x-icon">
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
diff --git a/static/debug.html b/static/debug.html
index 3fc6173f..e8c66767 100644
--- a/static/debug.html
+++ b/static/debug.html
@@ -6,7 +6,7 @@ just for immediate execution, without reporting to Karma server.
 -->
 <html>
 <head>
-%X_UA_COMPATIBLE%
+  %X_UA_COMPATIBLE%
   <title>Karma DEBUG RUNNER</title>
   <link href="favicon.ico" rel="icon" type="image/x-icon" />
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


Test patch:
diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js
index b6a0d5d5..4f6b873c 100644
--- a/test/unit/middleware/karma.spec.js
+++ b/test/unit/middleware/karma.spec.js
@@ -27,10 +27,10 @@ describe('middleware.karma', () => {
   const fsMock = mocks.fs.create({
     karma: {
       static: {
-        'client.html': mocks.fs.file(0, 'CLIENT HTML\n%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'),
+        'client.html': mocks.fs.file(0, 'CLIENT HTML%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'),
         'client_with_context.html': mocks.fs.file(0, 'CLIENT_WITH_CONTEXT\n%SCRIPT_URL_ARRAY%'),
         'context.html': mocks.fs.file(0, 'CONTEXT\n%SCRIPTS%'),
-        'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%\n%X_UA_COMPATIBLE%'),
+        'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%%X_UA_COMPATIBLE%'),
         'karma.js': mocks.fs.file(0, 'root: %KARMA_URL_ROOT%, proxy: %KARMA_PROXY_PATH%, v: %KARMA_VERSION%')
       }
     }
@@ -170,7 +170,7 @@ describe('middleware.karma', () => {
 
     response.once('end', () => {
       expect(nextSpy).not.to.have.been.called
-      expect(response).to.beServedAs(200, 'CLIENT HTML\n<meta http-equiv="X-UA-Compatible" content="xxx=yyy"/>?x-ua-compatible=xxx%3Dyyy')
+      expect(response).to.beServedAs(200, 'CLIENT HTML<meta http-equiv="X-UA-Compatible" content="xxx=yyy"/>?x-ua-compatible=xxx%3Dyyy')
       done()
     })
 
@@ -182,7 +182,7 @@ describe('middleware.karma', () => {
 
     response.once('end', () => {
       expect(nextSpy).not.to.have.been.called
-      expect(response).to.beServedAs(200, 'DEBUG\n\n<meta http-equiv="X-UA-Compatible" content="xxx=yyy"/>')
+      expect(response).to.beServedAs(200, 'DEBUG\n<meta http-equiv="X-UA-Compatible" content="xxx=yyy"/>')
       done()
     })