Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): a 3rd option to run the tests by dynamically loading test scripts without using iframe or new window #2542

Merged
merged 5 commits into from
Feb 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions client/karma.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,31 @@ var Karma = function (socket, iframe, opener, navigator, location) {
var childWindow = null
var navigateContextTo = function (url) {
if (self.config.useIframe === false) {
// If there is a window already open, then close it
// DEV: In some environments (e.g. Electron), we don't have setter access for location
if (childWindow !== null && childWindow.closed !== true) {
childWindow.close()
// run in new window
if (self.config.runInParent === false) {
// If there is a window already open, then close it
// DEV: In some environments (e.g. Electron), we don't have setter access for location
if (childWindow !== null && childWindow.closed !== true) {
childWindow.close()
}
childWindow = opener(url)
// run context on parent element and dynamically loading scripts
} else if (url !== 'about:blank') {
var loadScript = function (idx) {
if (idx < window.__karma__.scriptUrls.length) {
var ele = document.createElement('script')
ele.src = window.__karma__.scriptUrls[idx]
ele.onload = function () {
loadScript(idx + 1)
}
document.body.appendChild(ele)
} else {
window.__karma__.loaded()
}
}
loadScript(0)
}
childWindow = opener(url)
// run in iframe
} else {
iframe.src = url
}
Expand Down
6 changes: 6 additions & 0 deletions client/updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ var VERSION = require('./constants').VERSION

var StatusUpdater = function (socket, titleElement, bannerElement, browsersElement) {
var updateBrowsersInfo = function (browsers) {
if (!browsersElement) {
return
}
var items = []
var status
for (var i = 0; i < browsers.length; i++) {
Expand All @@ -13,6 +16,9 @@ var StatusUpdater = function (socket, titleElement, bannerElement, browsersEleme

var updateBanner = function (status) {
return function (param) {
if (!titleElement || !bannerElement) {
return
}
var paramStatus = param ? status.replace('$', param) : status
titleElement.innerHTML = 'Karma v' + VERSION + ' - ' + paramStatus
bannerElement.className = status === 'connected' ? 'online' : 'offline'
Expand Down
16 changes: 16 additions & 0 deletions docs/config/01-configuration-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,14 @@ How this value is used is up to your test adapter - you should check your adapte
If true, Karma runs the tests inside an iFrame. If false, Karma runs the tests in a new window. Some tests may not run in an
iFrame and may need a new window to run.

## client.runInParent
**Type:** Boolean

**Default:** `false`

**Description:** Run the tests on the same window as the client, without using iframe or a new window

If true, Karma runs the tests inside the original window without using iframe. It will load the test scripts dynamically.

## client.captureConsole
**Type:** Boolean
Expand Down Expand Up @@ -288,6 +296,14 @@ Disable this when you need to load external scripts that are served without the
**Description:** If `null` (default), uses karma's own `debug.html` file.


## customClientContextFile
**Type:** string

**Default:** `null`

**Description:** If `null` (default), uses karma's own `client_with_context.html` file (which is used when client.runInParent set to true).


## customHeaders
**Type:** Array

Expand Down
14 changes: 14 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,15 @@ var normalizeConfig = function (config, configFilePath) {
config.exclude = config.exclude.map(basePathResolve)
config.customContextFile = config.customContextFile && basePathResolve(config.customContextFile)
config.customDebugFile = config.customDebugFile && basePathResolve(config.customDebugFile)
config.customClientContextFile = config.customClientContextFile && basePathResolve(config.customClientContextFile)

// normalize paths on windows
config.basePath = helper.normalizeWinPath(config.basePath)
config.files = config.files.map(createPatternMapper(helper.normalizeWinPath))
config.exclude = config.exclude.map(helper.normalizeWinPath)
config.customContextFile = helper.normalizeWinPath(config.customContextFile)
config.customDebugFile = helper.normalizeWinPath(config.customDebugFile)
config.customClientContextFile = helper.normalizeWinPath(config.customClientContextFile)

// normalize urlRoot
config.urlRoot = normalizeUrlRoot(config.urlRoot)
Expand Down Expand Up @@ -183,6 +185,16 @@ var normalizeConfig = function (config, configFilePath) {
config.autoWatch = false
}

if (config.runInParent) {
log.debug('useIframe set to false, because using runInParent')
config.useIframe = false
}

if (!config.singleRun && !config.useIframe && config.runInParent) {
log.debug('singleRun set to true, because using runInParent')
config.singleRun = true
}

if (helper.isString(config.reporters)) {
config.reporters = config.reporters.split(',')
}
Expand Down Expand Up @@ -292,6 +304,7 @@ var Config = function () {
}
this.customContextFile = null
this.customDebugFile = null
this.customClientContextFile = null
this.exclude = []
this.logLevel = constant.LOG_INFO
this.colors = true
Expand All @@ -316,6 +329,7 @@ var Config = function () {
this.defaultClient = this.client = {
args: [],
useIframe: true,
runInParent: false,
captureConsole: true,
clearContext: true
}
Expand Down
45 changes: 33 additions & 12 deletions lib/middleware/karma.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ var createKarmaMiddleware = function (
var client = injector.get('config.client')
var customContextFile = injector.get('config.customContextFile')
var customDebugFile = injector.get('config.customDebugFile')
var customClientContextFile = injector.get('config.customClientContextFile')
var jsVersion = injector.get('config.jsVersion')
var includeCrossOriginAttribute = injector.get('config.crossOriginAttribute')

Expand All @@ -112,11 +113,16 @@ var createKarmaMiddleware = function (

// serve client.html
if (requestUrl === '/') {
return serveStaticFile('/client.html', requestedRangeHeader, response, function (data) {
return data
.replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
.replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url))
})
// redirect client_with_context.html
if (!client.useIframe && client.runInParent) {
requestUrl = '/client_with_context.html'
} else { // serve client.html
return serveStaticFile('/client.html', requestedRangeHeader, response, function (data) {
return data
.replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
.replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url))
})
}
}

// serve karma.js, context.js, and debug.js
Expand All @@ -139,11 +145,12 @@ var createKarmaMiddleware = function (
// or debug.html - execution context without channel to the server
var isRequestingContextFile = requestUrl === '/context.html'
var isRequestingDebugFile = requestUrl === '/debug.html'
if (isRequestingContextFile || isRequestingDebugFile) {
var isRequestingClientContextFile = requestUrl === '/client_with_context.html'
if (isRequestingContextFile || isRequestingDebugFile || isRequestingClientContextFile) {
return filesPromise.then(function (files) {
var fileServer
var requestedFileUrl
log.debug('custom files', customContextFile, customDebugFile)
log.debug('custom files', customContextFile, customDebugFile, customClientContextFile)
if (isRequestingContextFile && customContextFile) {
log.debug('Serving customContextFile %s', customContextFile)
fileServer = serveFile
Expand All @@ -152,6 +159,10 @@ var createKarmaMiddleware = function (
log.debug('Serving customDebugFile %s', customDebugFile)
fileServer = serveFile
requestedFileUrl = customDebugFile
} else if (isRequestingClientContextFile && customClientContextFile) {
log.debug('Serving customClientContextFile %s', customClientContextFile)
fileServer = serveFile
requestedFileUrl = customClientContextFile
} else {
log.debug('Serving static request %s', requestUrl)
fileServer = serveStaticFile
Expand All @@ -161,7 +172,10 @@ var createKarmaMiddleware = function (
fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) {
common.setNoCacheHeaders(response)

var scriptTags = files.included.map(function (file) {
var scriptTags = []
var scriptUrls = []
for (var i in files.included) {
var file = files.included[i]
var filePath = file.path
var fileExt = path.extname(filePath)

Expand All @@ -173,12 +187,16 @@ var createKarmaMiddleware = function (
}
}

scriptUrls.push(filePath)

if (fileExt === '.css') {
return util.format(LINK_TAG_CSS, filePath)
scriptTags.push(util.format(LINK_TAG_CSS, filePath))
continue
}

if (fileExt === '.html') {
return util.format(LINK_TAG_HTML, filePath)
scriptTags.push(util.format(LINK_TAG_HTML, filePath))
continue
}

// The script tag to be placed
Expand All @@ -190,8 +208,8 @@ var createKarmaMiddleware = function (
}

var crossOriginAttribute = includeCrossOriginAttribute ? CROSSORIGIN_ATTRIBUTE : ''
return util.format(SCRIPT_TAG, scriptType, filePath, crossOriginAttribute)
})
scriptTags.push(util.format(SCRIPT_TAG, scriptType, filePath, crossOriginAttribute))
}

// TODO(vojta): don't compute if it's not in the template
var mappings = files.served.map(function (file) {
Expand All @@ -206,11 +224,14 @@ var createKarmaMiddleware = function (

var clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n'

var scriptUrlsJS = 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n'

mappings = 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n'

return data
.replace('%SCRIPTS%', scriptTags.join('\n'))
.replace('%CLIENT_CONFIG%', clientConfig)
.replace('%SCRIPT_URL_ARRAY%', scriptUrlsJS)
.replace('%MAPPINGS%', mappings)
.replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
})
Expand Down
125 changes: 125 additions & 0 deletions static/client_with_context.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

<!DOCTYPE html>
<!--
This is the combined client and execution context.
Is used for single-shot tests.
-->
<html>
<head>

<title>Karma</title>
<link href="favicon.ico" rel="icon" type="image/x-icon">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<style type="text/css">
iframe {
height: 100%;
width: 100%;
border: 0;
}

html, body {
height: 100%;
padding: 0;
margin: 0;

font-family: sans-serif;
}

.offline {
background: #DDD;
}

.online {
background: #6C4;
}

.idle {
}

.executing {
background: #F99;
}

#banner {
padding: 5px 10px;
}

h1 {
font-size: 1.8em;
margin: 0;
padding: 0;
}

ul {
margin: 0;
padding: 0;

list-style: none;
}

li {
padding: 5px 12px;
}

.btn-debug {
float: right;
}

.offline .btn-debug {
display: none;
}

.btn-debug {
-moz-box-shadow:inset 0px 1px 0px 0px #ffffff;
-webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;
box-shadow:inset 0px 1px 0px 0px #ffffff;
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6) );
background:-moz-linear-gradient( center top, #ffffff 5%, #f6f6f6 100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6');
background-color:#ffffff;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
border:1px solid #dcdcdc;
display:inline-block;
color:#666666;
font-family:arial;
font-size:15px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
text-shadow:1px 1px 0px #ffffff;
}

.btn-debug:hover {
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff) );
background:-moz-linear-gradient( center top, #f6f6f6 5%, #ffffff 100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f6f6f6', endColorstr='#ffffff');
background-color:#f6f6f6;
}
</style>
</head>
<body>
<div id="banner" class="offline">
<h1 id="title">Karma - starting</h1>
</div>
<script src="socket.io/socket.io.js"></script>
<script src="karma.js"></script>
<script src="context.js"></script>
<!-- The scripts need to be at the end of body, so that some test running frameworks
(Angular Scenario, for example) need the body to be loaded so that it can insert its magic
into it. If it is before body, then it fails to find the body and crashes and burns in an epic
manner. -->
<script type="text/javascript">
// sets window.__karma__ and overrides console and error handling
%CLIENT_CONFIG%
window.__karma__.setupContext(window);

// All served files with the latest timestamps
%MAPPINGS%
%SCRIPT_URL_ARRAY%
</script>
<!-- Dynamically replaced with <script> tags -->
</body>
</html>
3 changes: 2 additions & 1 deletion test/client/karma.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ describe('Karma', function () {

it('should open a new window when useIFrame is false', function () {
var config = ck.config = {
useIframe: false
useIframe: false,
runInParent: false
}

socket.emit('execute', config)
Expand Down
Loading