diff --git a/test/in-plain-html-js/karma.conf.js b/test/in-plain-html-js/karma.conf.js
index ed37b08..1b85883 100644
--- a/test/in-plain-html-js/karma.conf.js
+++ b/test/in-plain-html-js/karma.conf.js
@@ -60,7 +60,11 @@ module.exports = function(config) {
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
- logLevel: config.LOG_INFO,
+ logLevel: config.LOG_WARN,
+
+ browserConsoleLogOptions: {
+ terminal: false,
+ },
// enable / disable watching file and executing tests whenever any file changes
diff --git a/test/in-plain-html-js/test/index.spec.js b/test/in-plain-html-js/test/index.spec.js
index f4d568a..542ab6e 100644
--- a/test/in-plain-html-js/test/index.spec.js
+++ b/test/in-plain-html-js/test/index.spec.js
@@ -110,7 +110,7 @@ describe('interactive demo', () => {
it('should move cursor before "c"', () => {
expect(firstInput.selectionStart).toBe(2, 'start');
expect(firstInput.selectionEnd).toBe(2, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
@@ -121,7 +121,7 @@ describe('interactive demo', () => {
it('should move cursor to the beginning', () => {
expect(firstInput.selectionStart).toBe(0, 'start');
expect(firstInput.selectionEnd).toBe(0, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
@@ -137,7 +137,7 @@ describe('interactive demo', () => {
it('should move cursor behind "b"', () => {
expect(firstInput.selectionStart).toBe(2, 'start');
expect(firstInput.selectionEnd).toBe(2, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
@@ -148,7 +148,7 @@ describe('interactive demo', () => {
it('should move cursor to the end', () => {
expect(firstInput.selectionStart).toBe(3, 'start');
expect(firstInput.selectionEnd).toBe(3, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
@@ -160,7 +160,7 @@ describe('interactive demo', () => {
expect(firstInput.value).toBe('bc', 'value');
expect(firstInput.selectionStart).toBe(0, 'start');
expect(firstInput.selectionEnd).toBe(0, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
@@ -172,7 +172,7 @@ describe('interactive demo', () => {
expect(firstInput.value).toBe('ac', 'value');
expect(firstInput.selectionStart).toBe(1, 'start');
expect(firstInput.selectionEnd).toBe(1, 'end');
- expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/, 'direction'));
+ expect(firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
});
});
});
@@ -187,6 +187,15 @@ describe('interactive demo', () => {
it('should *not* show control backspace', () => expect(testElement(id.control.backspace).offsetHeight).toBe(0));
it('should show control delete', () => expect(testElement(id.control.delete).offsetHeight).toBeGreaterThan(0));
+ describe('twice', () => {
+ beforeEach(() => emulateKey.mouse.hover(testElement(id.control.shift)));
+
+ it('should show control tab', () => expect(testElement(id.control.tab).offsetHeight).toBeGreaterThan(0));
+ it('should *not* show control shift-tab', () => expect(testElement(id.control.shiftTab).offsetHeight).toBe(0));
+ it('should show control backspace', () => expect(testElement(id.control.backspace).offsetHeight).toBeGreaterThan(0));
+ it('should *not* show control delete', () => expect(testElement(id.control.delete).offsetHeight).toBe(0));
+ });
+
describe(', focus first input', () => {
let firstInput;
diff --git a/test/in-plain-html-js/test/init-spec.js b/test/in-plain-html-js/test/init-spec.js
index d1127e4..2e0f111 100644
--- a/test/in-plain-html-js/test/init-spec.js
+++ b/test/in-plain-html-js/test/init-spec.js
@@ -4,7 +4,7 @@ function waitFor(description, test, retryDelay = [0, 1, 5, 10, 20, 100, 200, 500
const ready = test();
if (ready) return done();
if (currentTry > 3) {
- console.log('css not ready (' + (currentTry + 1) + ')');
+ console.log(description + ' not ready (' + (currentTry + 1) + ')');
}
const delay = retryDelay[currentTry++];
if (typeof delay !== 'number') {
diff --git a/test/in-typescript-requirejs/karma-proxies.js b/test/in-typescript-requirejs/karma-proxies.js
new file mode 100644
index 0000000..f8bd310
--- /dev/null
+++ b/test/in-typescript-requirejs/karma-proxies.js
@@ -0,0 +1,13 @@
+const karmaProxies = {
+ '/base/emulate-tab.js': '/base/node_modules/emulate-tab/dist/bundles/emulate-tab.amd.js',
+ '/base/emulate-key-in-browser.js': '/base/node_modules/emulate-key-in-browser/dist/bundles/emulate-key-in-browser.amd.js',
+ '/base/tslib.js': '/base/node_modules/tslib/tslib.js',
+ '/assets/': '/base/dist/assets/',
+ '/scripts/': '/base/src/',
+ '/styles/': '/base/src/',
+ '/app/': 'http://localhost:4300/',
+};
+
+if (typeof module !== 'undefined') {
+ module.exports = karmaProxies;
+}
\ No newline at end of file
diff --git a/test/in-typescript-requirejs/karma.conf.js b/test/in-typescript-requirejs/karma.conf.js
index f58b16f..737f6d7 100644
--- a/test/in-typescript-requirejs/karma.conf.js
+++ b/test/in-typescript-requirejs/karma.conf.js
@@ -1,8 +1,11 @@
// Karma configuration
-// Generated on Thu Jun 18 2020 08:31:24 GMT+0200 (GMT+02:00)
+// Generated on Tue Jun 30 2020 12:52:45 GMT+0200 (GMT+02:00)
+
+const withCoverage = true && process.env.COVERAGE;
+const tsConfig = require('./tsconfig.json');
module.exports = function(config) {
- console.log('orig config', config);
+ tsConfig.compilerOptions.module = 'amd';
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
@@ -11,42 +14,28 @@ module.exports = function(config) {
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
- frameworks: ['jasmine', 'fixture', 'karma-typescript'],
+ frameworks: ['jasmine', 'requirejs', 'fixture', 'karma-typescript'],
karmaTypescriptConfig: {
- ...require('./tsconfig.json'),
+ ...tsConfig,
coverageOptions: {
- instrumentation: false
+ instrumentation: withCoverage
}
},
- plugins: [
- 'karma-fixture',
- 'karma-typescript',
- 'karma-jasmine',
- 'karma-chrome-launcher',
- 'karma-firefox-launcher',
- 'karma-jasmine-html-reporter',
- 'karma-mocha-reporter',
- // require('karma-coverage-istanbul-reporter'),
- 'karma-html2js-preprocessor',
- ],
-
// list of files / patterns to load in the browser
files: [
- { pattern: 'node_modules/requirejs/require.js', included: false, watched: false },
- { pattern: 'dist/assets/*.*', included: false },
+ { pattern: 'src/**/*.html', included: true },
+ { pattern: 'src/**/*.ts', included: false },
{ pattern: 'src/**/*.css', included: false },
- 'src/**/*.html',
- 'src/**/*.@(spec|model|controller).@(ts|js)',
+ { pattern: 'dist/assets/*.*', included: false },
+ { pattern: 'node_modules/emulate-key-in-browser/dist/bundles/emulate-key-in-browser.amd.js', included: false },
+ { pattern: 'node_modules/emulate-tab/dist/bundles/emulate-tab.amd.js', included: false },
+ { pattern: 'node_modules/tslib/tslib.js', included: false },
+ 'karma-proxies.js',
+ 'test-main.js',
],
- proxies: {
- '/assets/': '/base/dist/assets/',
- '/scripts/require.js': '/base/node_modules/requirejs/require.js',
- '/scripts/': '/base/src/',
- '/styles/': '/base/src/',
- '/app/': 'http://localhost:4300/',
- },
+ proxies: require('./karma-proxies'),
// list of files / patterns to exclude
exclude: [
@@ -56,10 +45,8 @@ module.exports = function(config) {
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
- ...config.preprocessors,
- '**/*.js': [],
'**/*.html': ['html2js'],
- "**/*.ts": "karma-typescript" // *.tsx for React Jsx
+ "**/*.ts": "karma-typescript",
},
// test results reporter to use
@@ -81,7 +68,11 @@ module.exports = function(config) {
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
- logLevel: config.LOG_INFO,
+ logLevel: config.LOG_WARN,
+
+ browserConsoleLogOptions: {
+ terminal: false,
+ },
// enable / disable watching file and executing tests whenever any file changes
diff --git a/test/in-typescript-requirejs/package.json b/test/in-typescript-requirejs/package.json
index 2a9a5c4..d884d60 100644
--- a/test/in-typescript-requirejs/package.json
+++ b/test/in-typescript-requirejs/package.json
@@ -4,17 +4,14 @@
"description": "test emulate-key-in-browser in typescript with requirejs",
"main": "test.js",
"scripts": {
+ "prebuild": "npm i ../../tmp/emulate-key-in-browser.latest.tgz",
"build": "DEBUG=demo-build* node build.js",
"prestart": "npm run build",
"start": "node -r ts-node/register src/app.ts",
"start_watch": "npm-watch start",
"test": "karma start",
- "install-emulate-key-in-browser": "npm i ../../tmp/emulate-key-in-browser.latest.tgz",
- "uninstall-emulate-key-in-browser": "npm i ../../tmp/emulate-key-in-browser.latest.tgz",
- "reinstall-emulate-key-in-browser": "npm run uninstall-emulate-key-in-browser",
- "postreinstall-emulate-key-in-browser": "npm run install-emulate-key-in-browser",
- "precoverage": "npm run reinstall-emulate-key-in-browser",
- "coverage": "karma start --browsers=ChromeHeadless,FirefoxHeadless --single-run"
+ "precoverage": "npm run build",
+ "coverage": "COVERAGE=true karma start --browsers=ChromeHeadless,FirefoxHeadless --single-run"
},
"watch": {
"start": {
@@ -44,6 +41,7 @@
"karma-jasmine": "^3.3.1",
"karma-jasmine-html-reporter": "^1.5.4",
"karma-mocha-reporter": "^2.2.5",
+ "karma-requirejs": "^1.1.0",
"karma-typescript": "^5.0.3",
"npm-watch": "^0.6.0",
"ts-node": "^8.10.2",
diff --git a/test/in-typescript-requirejs/src/app.spec.ts b/test/in-typescript-requirejs/src/app.spec.ts
index 3901245..cfead9c 100644
--- a/test/in-typescript-requirejs/src/app.spec.ts
+++ b/test/in-typescript-requirejs/src/app.spec.ts
@@ -1,5 +1,5 @@
import { EventCheckController } from "./event-check.controller";
-import { waitFor } from './wait-for.model';
+import { waitFor } from './wait-for.controller';
xdescribe('demo app', () => {
let appFrame: HTMLIFrameElement;
@@ -19,7 +19,7 @@ xdescribe('demo app', () => {
appFrame.style.height = '100vh';
const loadedListener = () => {
appFrame.removeEventListener('load', loadedListener);
- waitFor('event check', () => !!(eventCheck = appFrame.contentWindow['eventCheck']), 100, 20).then(done);
+ waitFor('event check', () => !!(eventCheck = appFrame.contentWindow['eventCheck'])).then(done);
};
appFrame.addEventListener('load', loadedListener);
fixture.el.appendChild(appFrame);
diff --git a/test/in-typescript-requirejs/src/event-check.ts b/test/in-typescript-requirejs/src/event-check-init.ts
similarity index 100%
rename from test/in-typescript-requirejs/src/event-check.ts
rename to test/in-typescript-requirejs/src/event-check-init.ts
diff --git a/test/in-typescript-requirejs/src/event-check.controller.ts b/test/in-typescript-requirejs/src/event-check.controller.ts
index a3b74c4..1af8461 100644
--- a/test/in-typescript-requirejs/src/event-check.controller.ts
+++ b/test/in-typescript-requirejs/src/event-check.controller.ts
@@ -1,19 +1,53 @@
import { emulateKey } from 'emulate-key-in-browser';
+export const controlIds = {
+ container: 'controls',
+ shift: 'control-shift',
+ tab: 'control-tab',
+ shiftTab: 'control-shift-tab',
+ backspace: 'control-backspace',
+ delete: 'control-delete',
+ arrowUp: 'control-arrow-up',
+ arrowLeft: 'control-arrow-left',
+ arrowRight: 'control-arrow-right',
+ arrowDown: 'control-arrow-down',
+ writeA: 'control-write-a',
+ writeB: 'control-write-b',
+ writeC: 'control-write-c',
+ writeLeeroy: 'control-write-leeroy',
+ writeJenkins: 'control-write-jenkins',
+ writeLoremIpsum: 'control-write-lorem-ipsum',
+}
+
+export const viewIds = {
+ eventLog: 'event-log',
+ parentOfFirstInput: 'parent-of-first-input',
+ firstInput: 'first-input',
+ parentOfSecondInput: 'parent-of-second-input',
+ secondInput: 'second-input',
+ button: 'button',
+ parentOfHiddenInput: 'parent-of-hidden-input',
+ hiddenInput: 'hidden-input',
+}
+
+export type EventCheckControls = {
+ [key in keyof typeof controlIds]: HTMLDivElement;
+};
+
+export interface EventCheckView {
+ eventLog: HTMLPreElement,
+ parentOfFirstInput: HTMLDivElement,
+ firstInput: HTMLInputElement,
+ parentOfSecondInput: HTMLDivElement,
+ secondInput: HTMLInputElement,
+ button: HTMLButtonElement,
+ parentOfHiddenInput: HTMLDivElement,
+ hiddenInput: HTMLInputElement,
+}
+
export class EventCheckController {
- public view: {
- eventLog: HTMLPreElement,
- parentOfFirstInput: HTMLDivElement,
- firstInput: HTMLInputElement,
- parentOfSecondInput: HTMLDivElement,
- secondInput: HTMLInputElement,
- button: HTMLButtonElement,
- control: {
- container: HTMLDivElement,
- shift: HTMLDivElement,
- tab: HTMLDivElement,
- shiftTab: HTMLDListElement,
- }
+ public view: EventCheckView & {
+ control: EventCheckControls,
};
private cleanupTasks = new Array<() => PromiseLike | any>();
@@ -24,8 +58,10 @@ export class EventCheckController {
const classList = this.view.control.container.classList;
if (isActive) {
classList.add('shift');
+ this.activateShiftBehavior();
} else {
classList.remove('shift');
+ this.activateDefaultBehavior();
}
}
@@ -33,23 +69,21 @@ export class EventCheckController {
private parent = document,
) {
this.view = {
- eventLog: this.getElementById('event-log'),
- parentOfFirstInput: this.getElementById('parent-of-first-input'),
- firstInput: this.getElementById('first-input'),
- parentOfSecondInput: this.getElementById('parent-of-second-input'),
- secondInput: this.getElementById('second-input'),
- button: this.getElementById('button'),
- control: {
- container: this.getElementById('controls'),
- shift: this.getElementById('control-shift'),
- tab: this.getElementById('control-tab'),
- shiftTab: this.getElementById('control-shift-tab')
- }
+ ...this.getElementsByIds(viewIds),
+ control: this.getElementsByIds(controlIds),
};
}
+ private getElementsByIds(ids: { [key in keyof U]: string }): U {
+ return Object.entries(ids).reduce(
+ (mapped, [key, id]) => Object.assign(mapped, { [key]: this.getElementById(id) }),
+ {} as U
+ );
+ }
+
private getElementById(id: string): any {
const element = this.parent.getElementById(id);
+ /* istanbul ignore if */
if (!element) {
throw new Error(`element with id '${id}' not found`);
}
@@ -91,18 +125,44 @@ export class EventCheckController {
private initControls() {
const control = this.view.control;
- control.tab.onmouseover = () => {
- console.log('emulate tab');
- emulateKey.tab();
- }
- control.shiftTab.onmouseover = () => {
- console.log('emulate shift tab');
- emulateKey.shiftTab();
- }
control.shift.onmouseover = () => {
this.isShiftActive = !this.isShiftActive;
}
+ control.tab.onmouseover = () => emulateKey.tab();
+ control.shiftTab.onmouseover = () => emulateKey.shiftTab();
+ control.backspace.onmouseover = () => emulateKey.backspace();
+ control.delete.onmouseover = () => emulateKey.delete();
+ control.writeLeeroy.onmouseover = () => emulateKey.writeText('Leeroy');
+ control.writeJenkins.onmouseover = () => emulateKey.writeText('Jenkins');
+ control.writeLoremIpsum.onmouseover = () => emulateKey.writeText(loremIpsum);
+ this.activateDefaultBehavior();
+ }
+
+ private activateDefaultBehavior() {
+ const control = this.view.control;
+ control.arrowUp.onmouseover = () => emulateKey.arrow.up();
+ control.arrowLeft.onmouseover = () => emulateKey.arrow.left();
+ control.arrowRight.onmouseover = () => emulateKey.arrow.right();
+ control.arrowDown.onmouseover = () => emulateKey.arrow.down();
+ control.writeA.onmouseover = () => emulateKey.writeText('a');
+ control.writeB.onmouseover = () => emulateKey.writeText('b');
+ control.writeC.onmouseover = () => emulateKey.writeText('c');
+ }
+
+ private activateShiftBehavior() {
+ const control = this.view.control;
+ control.arrowUp.onmouseover = () => emulateKey.shiftArrow.up();
+ control.arrowLeft.onmouseover = () => emulateKey.shiftArrow.left();
+ control.arrowRight.onmouseover = () => emulateKey.shiftArrow.right();
+ control.arrowDown.onmouseover = () => emulateKey.shiftArrow.down();
+ control.writeA.onmouseover = () => emulateKey.writeText('A');
+ control.writeB.onmouseover = () => emulateKey.writeText('B');
+ control.writeC.onmouseover = () => emulateKey.writeText('C');
+ }
+
+ public destroy() {
+ this.cleanupTasks.forEach((cleanUpTask) => cleanUpTask());
}
}
-export default "bla";
\ No newline at end of file
+const loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.';
\ No newline at end of file
diff --git a/test/in-typescript-requirejs/src/event-check.html b/test/in-typescript-requirejs/src/event-check.html
index 4a5793b..ca0306b 100644
--- a/test/in-typescript-requirejs/src/event-check.html
+++ b/test/in-typescript-requirejs/src/event-check.html
@@ -41,6 +41,10 @@ demo form
+
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/test/in-typescript-requirejs/src/event-check.spec.ts b/test/in-typescript-requirejs/src/event-check.spec.ts
index d0f1e9f..903c6cf 100644
--- a/test/in-typescript-requirejs/src/event-check.spec.ts
+++ b/test/in-typescript-requirejs/src/event-check.spec.ts
@@ -1,9 +1,11 @@
-import { EventCheckController } from './event-check.controller';
+import { emulateKey } from 'emulate-key-in-browser';
+import { EventCheckController, EventCheckControls, EventCheckView } from './event-check.controller';
+import { waitFor } from './wait-for.controller';
describe('event check', () => {
let eventCheck: EventCheckController;
- let origLog: any;
- let logSpy: jasmine.Spy;
+ let control: EventCheckControls;
+ let view: EventCheckView;
function getEventLog(): string {
return eventCheck.view.eventLog.innerHTML;
@@ -15,37 +17,268 @@ describe('event check', () => {
});
beforeEach(() => {
- origLog = console.log;
- logSpy = spyOn(console, 'log');
fixture.cleanup();
fixture.load('event-check.html');
eventCheck = new EventCheckController();
eventCheck.init();
+ control = eventCheck.view.control;
+ view = eventCheck.view;
+ return waitFor('css', () => {
+ return view.hiddenInput && view.hiddenInput.offsetHeight === 0;
+ });
});
afterEach(() => {
- console.log = origLog;
- })
+ eventCheck.destroy();
+ });
it('should start', () => expect().nothing());
- describe('after write "a" into first input', () => {
+ describe('after hover tab', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.tab));
+
+ it('should focus first input', () => expect(document.activeElement).toBe(view.firstInput));
+ });
+
+ describe('after hover shift-tab', () => {
+ beforeEach(() => emulateKey.mouse.hover(control.shiftTab));
+
+ it('should focus first input', () => expect(document.activeElement).toBe(view.button))
+ });
+
+ describe('after focus first input', () => {
+
beforeEach(() => {
- const firstInput = eventCheck.view.firstInput;
- firstInput.value = 'a';
- const event = new KeyboardEvent('keydown', { code: 'keyA' });
- console.log('event', event);
- firstInput.dispatchEvent(event);
- return new Promise(done => setTimeout(done, 10));
+ view.firstInput.focus();
+ });
+
+ it('should focus first input', () => expect(document.activeElement).toBe(view.firstInput));
+ describe('and hover write-a', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeA));
+
+ it('should write "a" into first input', () => expect(view.firstInput.value).toBe('a'));
});
- it('log should contain entries', () => expect(getEventLog()).toContain('keyA'));
+ describe('and hover write-b', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeB));
+
+ it('should write "b" into first input', () => expect(view.firstInput.value).toBe('b'));
+ });
+
+ describe('and hover write-c', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeC));
+
+ it('should write "c" into first input', () => expect(view.firstInput.value).toBe('c'));
+ });
+
+ describe('and hover write-leeroy', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeLeeroy));
+
+ it('should write "Leeroy" into first input', () => expect(view.firstInput.value).toBe('Leeroy'));
+ });
+
+ describe('and hover write-jenkins', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeJenkins));
+
+ it('should write "Jenkins" into first input', () => expect(view.firstInput.value).toBe('Jenkins'));
+ });
+
+ describe('and hover write-lorem-ipsum', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeLoremIpsum));
+
+ it('should write lorem ipsum into first input', () => {
+ expect(view.firstInput.value).toEqual(jasmine.stringMatching(/^Lorem ipsum.{100,}/));
+ });
+ });
+
+ describe('then writing abc', () => {
+ beforeEach(() => view.firstInput.value = 'abc');
+
+ describe('and hover arrow-left', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowLeft));
+
+ it('should move cursor before "c"', () => {
+ expect(view.firstInput.selectionStart).toBe(2, 'start');
+ expect(view.firstInput.selectionEnd).toBe(2, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+
+ describe('and hover arrow-up', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowUp));
+
+ it('should move cursor to the beginning', () => {
+ expect(view.firstInput.selectionStart).toBe(0, 'start');
+ expect(view.firstInput.selectionEnd).toBe(0, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+
+ describe('then moving cursor after a', () => {
+ beforeEach(() => {
+ view.firstInput.selectionStart = view.firstInput.selectionEnd = 1;
+ });
+
+ describe('and hover arrow-right', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowRight));
+
+ it('should move cursor behind "b"', () => {
+ expect(view.firstInput.selectionStart).toBe(2, 'start');
+ expect(view.firstInput.selectionEnd).toBe(2, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+
+ describe('and hover arrow-down', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowDown));
+
+ it('should move cursor to the end', () => {
+ expect(view.firstInput.selectionStart).toBe(3, 'start');
+ expect(view.firstInput.selectionEnd).toBe(3, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+
+ describe('and hover backspace', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.backspace));
+
+ it('should remove "a"', () => {
+ expect(view.firstInput.value).toBe('bc', 'value');
+ expect(view.firstInput.selectionStart).toBe(0, 'start');
+ expect(view.firstInput.selectionEnd).toBe(0, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+
+ describe('and hover delete', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.delete));
+
+ it('should remove "b"', () => {
+ expect(view.firstInput.value).toBe('ac', 'value');
+ expect(view.firstInput.selectionStart).toBe(1, 'start');
+ expect(view.firstInput.selectionEnd).toBe(1, 'end');
+ expect(view.firstInput.selectionDirection).toEqual(jasmine.stringMatching(/none|forward/), 'direction');
+ });
+ });
+ });
+ })
+ });
+
+ describe('after hover shift', () => {
+ beforeEach(() => emulateKey.mouse.hover(control.shift));
+
+ it('should *not* show control tab', () => expect(control.tab.offsetHeight).toBe(0));
+ it('should show control shift-tab', () => expect(control.shiftTab.offsetHeight).toBeGreaterThan(0));
+ it('should *not* show control backspace', () => expect(control.backspace.offsetHeight).toBe(0));
+ it('should show control delete', () => expect(control.delete.offsetHeight).toBeGreaterThan(0));
+
+ describe('twice', () => {
+ beforeEach(() => emulateKey.mouse.hover(control.shift));
+
+ it('should show control tab', () => expect(control.tab.offsetHeight).toBeGreaterThan(0));
+ it('should *not* show control shift-tab', () => expect(control.shiftTab.offsetHeight).toBe(0));
+ it('should show control backspace', () => expect(control.backspace.offsetHeight).toBeGreaterThan(0));
+ it('should *not* show control delete', () => expect(control.delete.offsetHeight).toBe(0));
+ })
+
+ describe(', focus first input', () => {
+
+ beforeEach(() => view.firstInput.focus());
+
+ describe('and hover write-a', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeA));
+
+ it('should write "a" into first input', () => expect(view.firstInput.value).toBe('A'));
+ });
+
+ describe('and hover write-b', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeB));
+
+ it('should write "b" into first input', () => expect(view.firstInput.value).toBe('B'));
+ });
+
+ describe('and hover write-c', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.writeC));
+
+ it('should write "c" into first input', () => expect(view.firstInput.value).toBe('C'));
+ });
+
+ describe('then writing abc', () => {
+ beforeEach(() => view.firstInput.value = 'abc');
+
+ describe('and hover arrow-left', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowLeft));
+
+ it('should select "c"', () => {
+ expect(view.firstInput.selectionStart).toBe(2, 'start');
+ expect(view.firstInput.selectionEnd).toBe(3, 'end');
+ expect(view.firstInput.selectionDirection).toBe('backward', 'direction');
+ });
+ });
+
+ describe('and hover arrow-up', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowUp));
+
+ it('should select all up to the beginning', () => {
+ expect(view.firstInput.selectionStart).toBe(0, 'start');
+ expect(view.firstInput.selectionEnd).toBe(3, 'end');
+ expect(view.firstInput.selectionDirection).toBe('backward', 'direction');
+ });
+ });
+
+ describe('then moving cursor after a', () => {
+ beforeEach(() => {
+ view.firstInput.selectionStart = view.firstInput.selectionEnd = 1;
+ });
+
+ describe('and hover arrow-right', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowRight));
+
+ it('should select "b"', () => {
+ expect(view.firstInput.selectionStart).toBe(1, 'start');
+ expect(view.firstInput.selectionEnd).toBe(2, 'end');
+ expect(view.firstInput.selectionDirection).toBe('forward', 'direction');
+ });
+ });
+
+ describe('and hover arrow-down', () => {
+ shouldLog();
+ beforeEach(() => emulateKey.mouse.hover(control.arrowDown));
+
+ it('should select all to the end', () => {
+ expect(view.firstInput.selectionStart).toBe(1, 'start');
+ expect(view.firstInput.selectionEnd).toBe(3, 'end');
+ expect(view.firstInput.selectionDirection).toBe('forward', 'direction');
+ });
+ });
+ });
+ });
+ });
});
describe('after emulating tab', () => {
beforeEach(() => {
eventCheck.view.firstInput.focus();
- eventCheck.view.control.tab.onmouseover(new MouseEvent('mouseover'));
+ emulateKey.mouse.hover(eventCheck.view.control.tab);
return new Promise(done => setTimeout(done, 10));
});
@@ -62,7 +295,7 @@ describe('event check', () => {
`);
expect(actualEventLog).toEqual(expectedEventLog);
expect(eventCount(actualEventLog)).toEqual(eventCount(expectedEventLog));
- })
+ });
});
});
@@ -76,4 +309,23 @@ function normalizeEventLog(log: string) {
function eventCount(normalizedLog: string) {
return normalizedLog.split('\n').length - 1;
-}
\ No newline at end of file
+}
+
+function shouldLog(matcher?: jasmine.MatchableArgs[]) {
+ let origLog;
+ let logSpy;
+
+ beforeEach(() => {
+ origLog = console.log;
+ logSpy = spyOn(console, 'log');
+ });
+
+ afterEach(() => {
+ console.log = origLog;
+ if (matcher) {
+ expect(logSpy).toHaveBeenCalledWith(...matcher);
+ } else {
+ expect(logSpy).toHaveBeenCalled();
+ }
+ });
+}
diff --git a/test/in-typescript-requirejs/src/sample-form.spec.ts b/test/in-typescript-requirejs/src/sample-form.spec.ts
index 474cbb4..52e1906 100644
--- a/test/in-typescript-requirejs/src/sample-form.spec.ts
+++ b/test/in-typescript-requirejs/src/sample-form.spec.ts
@@ -1,5 +1,5 @@
import { emulateKey } from 'emulate-key-in-browser';
-import { waitFor } from './wait-for.model';
+import { waitFor } from './wait-for.controller';
describe('sample form', () => {
beforeAll(() => {
diff --git a/test/in-typescript-requirejs/src/wait-for.controller.ts b/test/in-typescript-requirejs/src/wait-for.controller.ts
new file mode 100644
index 0000000..ef4c77b
--- /dev/null
+++ b/test/in-typescript-requirejs/src/wait-for.controller.ts
@@ -0,0 +1,18 @@
+export function waitFor(description: string, test: () => boolean, retryDelay = [0, 1, 5, 10, 20, 100, 200, 500, 1000]) {
+ let currentTry = 0;
+ const waitLonger = (done) => {
+ const ready = test();
+ if (ready) return done();
+ /* istanbul ignore if */
+ if (currentTry > 3) {
+ console.log(description + ' not ready (' + (currentTry + 1) + ')');
+ }
+ const delay = retryDelay[currentTry++];
+ /* istanbul ignore if */
+ if (typeof delay !== 'number') {
+ throw new Error(`failed to wait for ${description} (tested ${currentTry} times)`);
+ }
+ setTimeout(() => waitLonger(done), delay);
+ }
+ return new Promise(resolve => waitLonger(resolve));
+}
diff --git a/test/in-typescript-requirejs/src/wait-for.model.ts b/test/in-typescript-requirejs/src/wait-for.model.ts
deleted file mode 100644
index f01cf34..0000000
--- a/test/in-typescript-requirejs/src/wait-for.model.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function waitFor(description: string, test: () => boolean, retryLimit = 20, milliseconsBetweenRetries = 200): Promise {
- let currentTry = 1;
- const waitLonger = (done) => {
- const ready = test();
- if (ready) return done();
- if (currentTry > 3) {
- console.log(description + ' not ready (' + currentTry + ')');
- }
- if (++currentTry > retryLimit) {
- throw new Error('failed to wait for ' + description);
- }
- setTimeout(() => waitLonger(done), milliseconsBetweenRetries);
- }
- return new Promise(resolve => waitLonger(resolve));
-}
diff --git a/test/in-typescript-requirejs/test-main.js b/test/in-typescript-requirejs/test-main.js
new file mode 100644
index 0000000..8225158
--- /dev/null
+++ b/test/in-typescript-requirejs/test-main.js
@@ -0,0 +1,30 @@
+var allTestFiles = []
+var TEST_REGEXP = /(spec|test)\.js$/i
+
+// Get a list of all the test files to include
+Object.keys(window.__karma__.files).forEach(function (file) {
+ if (TEST_REGEXP.test(file)) {
+ // Normalize paths to RequireJS module names.
+ // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
+ // then do not normalize the paths
+ var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '')
+ allTestFiles.push(normalizedTestModule)
+ }
+})
+
+Object.entries(karmaProxies).forEach(([from, to]) => {
+ if (from.startsWith('/base') && to.startsWith('/base')) {
+ window.__karma__.files[from] = window.__karma__.files[to];
+ }
+});
+
+require.config({
+ // Karma serves files under /base, which is the basePath from your config file
+ baseUrl: '/base',
+
+ // dynamically load all test files
+ deps: allTestFiles,
+
+ // we have to kickoff jasmine, as it is asynchronous
+ callback: window.__karma__.start
+})