Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1284 from adobe/jason-sanjose/issue-1275

Prevent extensions from loading in test windows
  • Loading branch information...
commit 03d2b45b8a2d4cc574a03ea67eb3f5b5ffbc4c57 2 parents de3dbfc + 8c501a8
@redmunds redmunds authored
View
18 src/brackets.js
@@ -78,12 +78,17 @@ define(function (require, exports, module) {
Dialogs = require("widgets/Dialogs"),
ExtensionLoader = require("utils/ExtensionLoader"),
SidebarView = require("project/SidebarView"),
- Async = require("utils/Async");
+ Async = require("utils/Async"),
+ UrlParams = require("utils/UrlParams").UrlParams;
// Local variables
- var bracketsReady = false,
- bracketsReadyHandlers = [];
-
+ var bracketsReady = false,
+ bracketsReadyHandlers = [],
+ params = new UrlParams();
+
+ // read URL params
+ params.parse();
+
//Load modules that self-register and just need to get included in the main project
require("document/ChangedDocumentTracker");
require("editor/EditorCommandHandlers");
@@ -175,7 +180,10 @@ define(function (require, exports, module) {
// TODO: (issue 1029) Add timeout to main extension loading promise, so that we always call this function
// Making this fix will fix a warning (search for issue 1029) related to the brackets 'ready' event.
function _initExtensions() {
- return Async.doInParallel(["default", "user"], function (item) {
+ // allow unit tests to override which plugin folder(s) to load
+ var paths = params.get("extensions") || "default,user";
+
+ return Async.doInParallel(paths.split(","), function (item) {
return ExtensionLoader.loadAllExtensionsInNativeDirectory(
FileUtils.getNativeBracketsDirectoryPath() + "/extensions/" + item,
"extensions/" + item
View
2  src/extensions/default/JavaScriptQuickEdit/unittests.js
@@ -279,7 +279,7 @@ define(function (require, exports, module) {
describe("Performance suite", function () {
- this.performance = true;
+ this.category = "performance";
var testPath = SpecRunnerUtils.getTestPath("/../../../brackets-scenario/jquery-ui/");
View
15 src/utils/PerfUtils.js
@@ -316,6 +316,20 @@ define(function (require, exports, module) {
return perfData[toMeasurementId(name)];
}
+ function searchData(regExp) {
+ var keys = Object.keys(perfData).filter(function (key) {
+ return regExp.test(key);
+ });
+
+ var datas = [];
+
+ keys.forEach(function (key) {
+ datas.push(perfData[key]);
+ });
+
+ return datas;
+ }
+
/**
* Clear all logs including metric data and active tests.
*/
@@ -336,6 +350,7 @@ define(function (require, exports, module) {
exports.isActive = isActive;
exports.markStart = markStart;
exports.getData = getData;
+ exports.searchData = searchData;
exports.updateMeasurement = updateMeasurement;
exports.getDelimitedPerfData = getDelimitedPerfData;
exports.createPerfMeasurement = createPerfMeasurement;
View
92 src/utils/UrlParams.js
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+
+/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
+/*global define, window */
+
+define(function (require, exports, module) {
+ "use strict";
+
+ /**
+ * Convert between URL querystring and name/value pairs. Decodes and encodes URL parameters.
+ */
+ function UrlParams() {
+ this._store = {};
+ }
+
+ /**
+ * Parse the window location by default. Optionally specify a URL to parse.
+ * @param {string} url
+ */
+ UrlParams.prototype.parse = function (url) {
+ if (url) {
+ url = url.substring(indexOf("?") + 1);
+ } else {
+ url = window.document.location.search.substring(1);
+ }
+
+ var urlParams = url.split("&"),
+ p,
+ self = this;
+
+ urlParams.forEach(function (param) {
+ p = param.split("=");
+ self._store[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+ });
+ };
+
+ /**
+ * Store a name/value string pair
+ * @param {!string} name
+ * @param {!string} value
+ */
+ UrlParams.prototype.put = function (name, value) {
+ this._store[name] = value;
+ };
+
+ /**
+ * Retreive a value by name
+ * @param {!string} name
+ */
+ UrlParams.prototype.get = function (name) {
+ return this._store[name];
+ };
+
+ /**
+ * Encode name/value pairs as URI components.
+ */
+ UrlParams.prototype.toString = function () {
+ var strs = [],
+ self = this;
+
+ Object.keys(self._store).forEach(function (key) {
+ strs.push(encodeURIComponent(key) + "=" + encodeURIComponent(self._store[key]));
+ });
+
+ return strs.join("&");
+ };
+
+ // Define public API
+ exports.UrlParams = UrlParams;
+});
View
25 test/BootstrapReporter.js
@@ -1,32 +1,29 @@
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50, forin: true */
-/*global jasmine, document */
-(function ($) {
+/*global jasmine, $, define, document, require */
+define(function (require, exports, module) {
'use strict';
+
+ var UrlParams = require("utils/UrlParams").UrlParams;
jasmine.BootstrapReporter = function (doc, filter) {
- this._paramMap = {};
this.document = doc || document;
this._env = jasmine.getEnv();
+ this.params = new UrlParams();
+ this.params.parse();
// parse querystring
var self = this,
- params = this.document.location.search.substring(1).split('&'),
i,
p;
- for (i = 0; i < params.length; i++) {
- p = params[i].split('=');
- this._paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
- }
-
- this._runAll = this._paramMap.spec === "All";
+ this._runAll = this.params.get("spec") === "All";
// _topLevelFilter is applied first - selects Performance vs. Unit test suites
this._topLevelFilter = filter;
// Jasmine's runner uses the specFilter to choose which tests to run.
// If you selected an option other than "All" this will be a subset of all tests loaded.
- this._env.specFilter = this.createSpecFilter(this._paramMap.spec);
+ this._env.specFilter = this.createSpecFilter(this.params.get("spec"));
this._runner = this._env.currentRunner();
// build DOM immediately
@@ -187,7 +184,7 @@
this._createSuiteList();
// highlight the current suite
- topLevelData = (this._paramMap.spec) ? this._topLevelSuiteMap[this._paramMap.spec] : null;
+ topLevelData = (this.params.get("spec")) ? this._topLevelSuiteMap[this.params.get("spec")] : null;
if (topLevelData) {
topLevelData.$listItem.toggleClass("active", true);
@@ -229,7 +226,7 @@
passed,
data = this._topLevelSuiteMap[suite.getFullName()];
- if ((suite.getFullName() === this._paramMap.spec) && data) {
+ if ((suite.getFullName() === this.params.get("spec")) && data) {
passed = results.passed();
data.$badgeAll.hide();
@@ -354,4 +351,4 @@
jasmine.BootstrapReporter.prototype.log = function (str) {
};
-}(window.jQuery));
+});
View
2  test/PerformanceTestSuite.js
@@ -26,6 +26,6 @@
define(function (require, exports, module) {
'use strict';
- // Each suite or spec must have this.performance = true to be filtered properly
+ // Each suite or spec must have this.category === "performance" to be filtered properly
require("perf/Performance-test");
});
View
4 test/SpecRunner.html
@@ -32,14 +32,11 @@
<link href="BootstrapReporter.css" rel="stylesheet">
<script src="thirdparty/jasmine-core/jasmine.js"></script>
- <script src="thirdparty/jasmine-core/jasmine-html.js"></script>
- <script src="thirdparty/jasmine-jquery-1.3.1.js"></script>
<!-- Pre-load third party scripts that cannot be async loaded. -->
<script src="../src/thirdparty/jquery-1.7.min.js"></script>
<script src="../src/thirdparty/CodeMirror2/lib/codemirror.js"></script>
<script src="thirdparty/bootstrap2/js/bootstrap.min.js"></script>
- <script src="BootstrapReporter.js"></script>
<!-- All other scripts are loaded through require. -->
<script src="../src/thirdparty/require.js" data-main="SpecRunner"></script>
@@ -61,6 +58,7 @@
<ul class="nav">
<li><a id="UnitTestSuite" href="?suite=UnitTestSuite">Unit</a></li>
<li><a id="PerformanceTestSuite" href="?suite=PerformanceTestSuite">Performance</a></li>
+ <li><a id="ExtensionSuite" href="?suite=ExtensionTestSuite">Extensions</a></li>
<li><a id="reload" href="#">Reload</a></li>
<li><a id="show-dev-tools" href="#">Show Developer Tools</a></li>
</ul>
View
108 test/SpecRunner.js
@@ -44,7 +44,11 @@ define(function (require, exports, module) {
ExtensionLoader = require("utils/ExtensionLoader"),
Async = require("utils/Async"),
FileUtils = require("file/FileUtils"),
- Menus = require("command/Menus");
+ Menus = require("command/Menus"),
+ UrlParams = require("utils/UrlParams").UrlParams;
+
+ // Jasmine reporter UI
+ require("test/BootstrapReporter");
// TODO: Issue 949 - the following code should be shared
// Load modules that self-register and just need to get included in the main project
@@ -54,29 +58,31 @@ define(function (require, exports, module) {
require("test/UnitTestSuite");
require("test/PerformanceTestSuite");
- var suite;
-
- function getParamMap() {
- var params = document.location.search.substring(1).split('&'),
- paramMap = {},
- i,
- p;
+ var suite,
+ params = new UrlParams();
- for (i = 0; i < params.length; i++) {
- p = params[i].split('=');
- paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
- }
-
- return paramMap;
- }
+ params.parse();
- function _loadExtensionTests() {
- var bracketsPath = FileUtils.getNativeBracketsDirectoryPath();
+ function _loadExtensionTests(suite) {
+ // augment jasmine to identify extension unit tests
+ var addSuite = jasmine.Runner.prototype.addSuite;
+ jasmine.Runner.prototype.addSuite = function (suite) {
+ suite.category = "extension";
+ addSuite.call(this, suite);
+ };
+
+ var bracketsPath = FileUtils.getNativeBracketsDirectoryPath(),
+ paths = ["default"];
+
+ // load user extensions only when running the extension test suite
+ if (suite === "ExtensionTestSuite") {
+ paths.push("user");
+ }
// This returns path to test folder, so convert to src
bracketsPath = bracketsPath.replace("brackets/test", "brackets/src");
- return Async.doInParallel(["default", "user"], function (dir) {
+ return Async.doInParallel(paths, function (dir) {
return ExtensionLoader.testAllExtensionsInNativeDirectory(
bracketsPath + "/extensions/" + dir,
"extensions/" + dir
@@ -123,8 +129,47 @@ define(function (require, exports, module) {
// Note: we change the name to "getModule" because this won't do exactly the same thing as 'require' in AMD-wrapped
// modules. The extension will only be able to load modules that have already been loaded once.
brackets.getModule = require;
+
+ suite = params.get("suite") || localStorage.getItem("SpecRunner.suite") || "UnitTestSuite";
- _loadExtensionTests().done(function () {
+ // Create a top-level filter to show/hide performance and extensions tests
+ var isPerfSuite = (suite === "PerformanceTestSuite"),
+ isExtSuite = (suite === "ExtensionTestSuite");
+
+ var topLevelFilter = function (spec) {
+ if (!isPerfSuite && !isExtSuite) {
+ return !spec.category;
+ }
+
+ var category = (isPerfSuite) ? "performance" : "extension";
+
+ if (spec.category === category) {
+ return true;
+ }
+
+ var suite = spec.suite;
+
+ while (suite) {
+ if (suite.category === category) {
+ return true;
+ }
+
+ suite = suite.parentSuite;
+ }
+
+ return false;
+ };
+
+ /*
+ * TODO (jason-sanjose): extension unit tests should only load the
+ * extension and the extensions dependencies. We should not load
+ * unrelated extensions. Currently, this solution is all or nothing.
+ */
+
+ // configure spawned test windows to load extensions
+ SpecRunnerUtils.setLoadExtensionsInTestWindow(isExtSuite);
+
+ _loadExtensionTests(suite).done(function () {
var jasmineEnv = jasmine.getEnv();
// Initiailize unit test preferences for each spec
@@ -140,35 +185,14 @@ define(function (require, exports, module) {
jasmineEnv.updateInterval = 1000;
- suite = getParamMap().suite || localStorage.getItem("SpecRunner.suite") || "UnitTestSuite";
-
- // Create a top-level filter to show/hide performance tests
- var isPerfSuite = (suite === "PerformanceTestSuite"),
- performanceFilter = function (spec) {
- if (spec.performance === true) {
- return isPerfSuite;
- }
-
- var suite = spec.suite;
-
- while (suite) {
- if (suite.performance === true) {
- return isPerfSuite;
- }
-
- suite = suite.parentSuite;
- }
-
- return !isPerfSuite;
- };
-
- jasmineEnv.addReporter(new jasmine.BootstrapReporter(document, performanceFilter));
+ jasmineEnv.addReporter(new jasmine.BootstrapReporter(document, topLevelFilter));
// add performance reporting
if (isPerfSuite) {
jasmineEnv.addReporter(new PerformanceReporter());
}
+ // remember the suite for the next unit test window launch
localStorage.setItem("SpecRunner.suite", suite);
$(window.document).ready(_documentReadyHandler);
View
17 test/perf/Performance-test.js
@@ -22,7 +22,7 @@
*/
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
-/*global define, describe, beforeEach, afterEach, it, runs, waitsFor, expect, brackets */
+/*global define, describe, beforeEach, afterEach, it, runs, waitsFor, waitsForDone, expect, brackets */
// TODO: Eventually we should have a brackets performance test suite that is separate from the unit tests
@@ -43,7 +43,7 @@ define(function (require, exports, module) {
describe("Performance Tests", function () {
- this.performance = true;
+ this.category = "performance";
// Note: this tests assumes that the "brackets-scenario" repo is in the same folder
// as the "brackets-app"
@@ -54,19 +54,14 @@ define(function (require, exports, module) {
testWindow;
function openFile(path) {
- var didOpen = false, gotError = false;
-
+ var fullPath = testPath + path;
runs(function () {
- CommandManager.execute(Commands.FILE_OPEN, {fullPath: testPath + path})
- .done(function () {
- didOpen = true;
- })
- .fail(function () { gotError = true; });
+ var promise = CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath});
+ waitsForDone(promise);
});
- waitsFor(function () { return didOpen && !gotError; }, 1000);
runs(function () {
- PerformanceReporter.logTestWindow(PerfUtils.OPEN_FILE, path);
+ PerformanceReporter.logTestWindow(/Open File:\t,*/, path);
PerformanceReporter.clearTestWindow();
});
}
View
14 test/perf/PerformanceReporter.js
@@ -38,16 +38,22 @@ define(function (require, exports, module) {
}
function _logTestWindowMeasurement(measureInfo) {
- var value = currentPerfUtils.getData(measureInfo.measure.id),
- printName = measureInfo.measure.name,
+ var value,
+ printName = measureInfo.measure.name || measureInfo.name,
record = {};
+ if (measureInfo.measure instanceof RegExp) {
+ value = currentPerfUtils.searchData(measureInfo.measure);
+ } else {
+ value = currentPerfUtils.getData(measureInfo.measure.id);
+ }
+
if (value === undefined) {
value = "(None)";
}
- if (measureInfo.name) {
- printName = printName + " - " + measureInfo.name;
+ if (measureInfo.measure.name && measureInfo.name) {
+ printName = measureInfo.measure.name + " - " + measureInfo.name;
}
if (measureInfo.operation === "sum") {
View
80 test/spec/SpecRunnerUtils.js
@@ -31,13 +31,15 @@ define(function (require, exports, module) {
Commands = require("command/Commands"),
FileUtils = require("file/FileUtils"),
Async = require("utils/Async"),
- DocumentManager = require("document/DocumentManager");
+ DocumentManager = require("document/DocumentManager"),
+ UrlParams = require("utils/UrlParams").UrlParams;
var TEST_PREFERENCES_KEY = "com.adobe.brackets.test.preferences",
OPEN_TAG = "{{",
CLOSE_TAG = "}}",
RE_MARKER = /[^\\]?\{\{(\d+)[^\\]?\}\}/g,
- testWindow;
+ _testWindow,
+ _doLoadExtensions;
function getTestRoot() {
// /path/to/brackets/test/SpecRunner.html
@@ -59,7 +61,6 @@ define(function (require, exports, module) {
return path.join("/");
}
-
/**
* Utility for tests that wait on a Promise to complete. Placed in the global namespace so it can be used
* similarly to the standards Jasmine waitsFor(). Unlike waitsFor(), must be called from INSIDE
@@ -128,24 +129,30 @@ define(function (require, exports, module) {
testWindowY = window.screen.availHeight - testWindowHt,
optionsStr = "left=" + testWindowX + ",top=" + testWindowY +
",width=" + testWindowWid + ",height=" + testWindowHt;
- testWindow = window.open(getBracketsSourceRoot() + "/index.html", "_blank", optionsStr);
- testWindow.executeCommand = function executeCommand(cmd, args) {
- return testWindow.brackets.test.CommandManager.execute(cmd, args);
+ var params = new UrlParams();
+
+ // setup extension loading in the test window
+ params.put("extensions", _doLoadExtensions ? "default,user" : "default");
+
+ _testWindow = window.open(getBracketsSourceRoot() + "/index.html?" + params.toString(), "_blank", optionsStr);
+
+ _testWindow.executeCommand = function executeCommand(cmd, args) {
+ return _testWindow.brackets.test.CommandManager.execute(cmd, args);
};
});
// FIXME (issue #249): Need an event or something a little more reliable...
waitsFor(
function isBracketsDoneLoading() {
- return testWindow.brackets && testWindow.brackets.test && testWindow.brackets.test.doneLoading;
+ return _testWindow.brackets && _testWindow.brackets.test && _testWindow.brackets.test.doneLoading;
},
10000
);
runs(function () {
// callback allows specs to query the testWindow before they run
- callback.call(spec, testWindow);
+ callback.call(spec, _testWindow);
});
}
@@ -156,7 +163,7 @@ define(function (require, exports, module) {
runs(function () {
//we need to mark the documents as not dirty before we close
//or the window will stay open prompting to save
- var openDocs = testWindow.brackets.test.DocumentManager.getAllOpenDocuments();
+ var openDocs = _testWindow.brackets.test.DocumentManager.getAllOpenDocuments();
openDocs.forEach(function resetDoc(doc) {
if (doc.isDirty) {
//just refresh it back to it's current text. This will mark it
@@ -164,7 +171,7 @@ define(function (require, exports, module) {
doc.refreshText(doc.getText(), doc.diskTimestamp);
}
});
- testWindow.close();
+ _testWindow.close();
});
}
@@ -178,7 +185,7 @@ define(function (require, exports, module) {
*/
function clickDialogButton(buttonId) {
// Make sure there's one and only one dialog open
- var $dlg = testWindow.$(".modal.instance"),
+ var $dlg = _testWindow.$(".modal.instance"),
promise = $dlg.data("promise");
expect($dlg.length).toBe(1);
@@ -200,7 +207,7 @@ define(function (require, exports, module) {
runs(function () {
// begin loading project path
- var result = testWindow.brackets.test.ProjectManager.openProject(path);
+ var result = _testWindow.brackets.test.ProjectManager.openProject(path);
result.done(function () {
isReady = true;
});
@@ -268,7 +275,7 @@ define(function (require, exports, module) {
* @return {!Array.<string>|string} Absolute file path(s)
*/
function makeAbsolute(paths) {
- var fullPath = testWindow.brackets.test.ProjectManager.getProjectRoot().fullPath;
+ var fullPath = _testWindow.brackets.test.ProjectManager.getProjectRoot().fullPath;
function prefixProjectPath(path) {
if (path.indexOf(fullPath) === 0) {
@@ -292,7 +299,7 @@ define(function (require, exports, module) {
* @return {!Array.<string>|string} Relative file path(s)
*/
function makeRelative(paths) {
- var fullPath = testWindow.brackets.test.ProjectManager.getProjectRoot().fullPath,
+ var fullPath = _testWindow.brackets.test.ProjectManager.getProjectRoot().fullPath,
fullPathLength = fullPath.length;
function removeProjectPath(path) {
@@ -351,7 +358,7 @@ define(function (require, exports, module) {
fullpaths = makeArray(makeAbsolute(paths)),
keys = makeArray(makeRelative(paths)),
docs = {},
- FileViewController = testWindow.brackets.test.FileViewController;
+ FileViewController = _testWindow.brackets.test.FileViewController;
Async.doSequentially(fullpaths, function (path, i) {
var one = new $.Deferred();
@@ -456,7 +463,7 @@ define(function (require, exports, module) {
function toggleQuickEditAtOffset(editor, offset) {
editor.setCursorPos(offset.line, offset.ch);
- return testWindow.executeCommand(Commands.TOGGLE_QUICK_EDIT);
+ return _testWindow.executeCommand(Commands.TOGGLE_QUICK_EDIT);
}
/**
@@ -523,26 +530,31 @@ define(function (require, exports, module) {
}
function getTestWindow() {
- return testWindow;
+ return _testWindow;
+ }
+
+ function setLoadExtensionsInTestWindow(doLoadExtensions) {
+ _doLoadExtensions = doLoadExtensions;
}
exports.TEST_PREFERENCES_KEY = TEST_PREFERENCES_KEY;
- exports.getTestRoot = getTestRoot;
- exports.getTestPath = getTestPath;
- exports.getBracketsSourceRoot = getBracketsSourceRoot;
- exports.makeAbsolute = makeAbsolute;
- exports.createMockDocument = createMockDocument;
- exports.createTestWindowAndRun = createTestWindowAndRun;
- exports.closeTestWindow = closeTestWindow;
- exports.clickDialogButton = clickDialogButton;
- exports.loadProjectInTestWindow = loadProjectInTestWindow;
- exports.openProjectFiles = openProjectFiles;
- exports.toggleQuickEditAtOffset = toggleQuickEditAtOffset;
- exports.saveFilesWithOffsets = saveFilesWithOffsets;
- exports.saveFilesWithoutOffsets = saveFilesWithoutOffsets;
- exports.saveFileWithoutOffsets = saveFileWithoutOffsets;
- exports.deleteFile = deleteFile;
- exports.getTestWindow = getTestWindow;
- exports.simulateKeyEvent = simulateKeyEvent;
+ exports.getTestRoot = getTestRoot;
+ exports.getTestPath = getTestPath;
+ exports.getBracketsSourceRoot = getBracketsSourceRoot;
+ exports.makeAbsolute = makeAbsolute;
+ exports.createMockDocument = createMockDocument;
+ exports.createTestWindowAndRun = createTestWindowAndRun;
+ exports.closeTestWindow = closeTestWindow;
+ exports.clickDialogButton = clickDialogButton;
+ exports.loadProjectInTestWindow = loadProjectInTestWindow;
+ exports.openProjectFiles = openProjectFiles;
+ exports.toggleQuickEditAtOffset = toggleQuickEditAtOffset;
+ exports.saveFilesWithOffsets = saveFilesWithOffsets;
+ exports.saveFilesWithoutOffsets = saveFilesWithoutOffsets;
+ exports.saveFileWithoutOffsets = saveFileWithoutOffsets;
+ exports.deleteFile = deleteFile;
+ exports.getTestWindow = getTestWindow;
+ exports.simulateKeyEvent = simulateKeyEvent;
+ exports.setLoadExtensionsInTestWindow = setLoadExtensionsInTestWindow;
});
Please sign in to comment.
Something went wrong with that request. Please try again.