Skip to content

Commit 07a2486

Browse files
committed
feat(typescript): add types
1 parent 27b4850 commit 07a2486

File tree

7 files changed

+142
-59
lines changed

7 files changed

+142
-59
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ describe('tests with webdriver', function() {
6161
})
6262
```
6363

64+
TypeScript
65+
----------
66+
67+
For the typings related to the changes in the global jasmine variables (e.g.
68+
allowing `it()` blocks to return a promise), we publish the package
69+
`@types/jasminewd2`. If you are writing tests using jasminewd (including
70+
Protractor tests), be sure to include `@types/jasminewd2` in your
71+
`devDependencies`, as these global type modifications are ***not*** bundled with
72+
the `jasminewd2` npm module.
73+
74+
jasminewd also exports one function directly: `init`. Unfortunately, we do not
75+
publish typings for this function. If you call this function directly (e.g. you
76+
are a Protractor dev), you should simply do:
77+
78+
```ts
79+
require('jasminewd2').init(controlFlow);
80+
```
81+
6482
`async` functions / `await`
6583
---------------------------
6684

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"selenium-webdriver": "3.0.1"
1717
},
1818
"devDependencies": {
19+
"@types/jasmine": "^2.5.40",
1920
"@types/node": "^6.0.56",
2021
"@types/selenium-webdriver": "^2.53.38",
2122
"jasmine": "2.4.1",

spec/@types_jasminewd2.d.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// This is jasminewd's internal version of @types/jasminewd2. If you need types
2+
// for jasminewd2, please use @types/jasminewd2 instead
3+
4+
// Type definitions for jasminewd2
5+
// Project https://github.com/angular/jasminewd
6+
// Definitions by: Sammy Jelin <https://github.com/sjelin>
7+
8+
declare function it(expectation: string, assertion?: () => Promise<void>, timeout?: number): void;
9+
declare function fit(expectation: string, assertion?: () => Promise<void>, timeout?: number): void;
10+
declare function xit(expectation: string, assertion?: () => Promise<void>, timeout?: number): void;
11+
declare function beforeEach(action: () => Promise<void>, timeout?: number): void;
12+
declare function afterEach(action: () => Promise<void>, timeout?: number): void;
13+
declare function beforeAll(action: () => Promise<void>, timeout?: number): void;
14+
declare function afterAll(action: () => Promise<void>, timeout?: number): void;
15+
16+
declare namespace jasmine {
17+
// The global `Promise` type is too strict and kinda wrong
18+
interface Promise<T> {
19+
then<U>(onFulfill?: (value: T) => U | Promise<U>, onReject?: (error: any) => U | Promise<U>): Promise<U>;
20+
}
21+
22+
interface Matchers {
23+
toBe(expected: any, expectationFailOutput?: any): Promise<void>;
24+
toEqual(expected: any, expectationFailOutput?: any): Promise<void>;
25+
toMatch(expected: string | RegExp | Promise<string | RegExp>, expectationFailOutput?: any): Promise<void>;
26+
toBeDefined(expectationFailOutput?: any): Promise<void>;
27+
toBeUndefined(expectationFailOutput?: any): Promise<void>;
28+
toBeNull(expectationFailOutput?: any): Promise<void>;
29+
toBeNaN(): Promise<void>;
30+
toBeTruthy(expectationFailOutput?: any): Promise<void>;
31+
toBeFalsy(expectationFailOutput?: any): Promise<void>;
32+
toHaveBeenCalled(): Promise<void>;
33+
toHaveBeenCalledWith(...params: any[]): Promise<void>;
34+
toHaveBeenCalledTimes(expected: number | Promise<number>): Promise<void>;
35+
toContain(expected: any, expectationFailOutput?: any): Promise<void>;
36+
toBeLessThan(expected: number | Promise<number>, expectationFailOutput?: any): Promise<void>;
37+
toBeLessThanOrEqual(expected: number | Promise<number>, expectationFailOutput?: any): Promise<void>;
38+
toBeGreaterThan(expected: number | Promise<number>, expectationFailOutput?: any): Promise<void>;
39+
toBeGreaterThanOrEqual(expected: number | Promise<number>, expectationFailOutput?: any): Promise<void>;
40+
toBeCloseTo(expected: number | Promise<number>, precision?: any, expectationFailOutput?: any): Promise<void>;
41+
toThrow(expected?: any): Promise<void>;
42+
toThrowError(message?: string | RegExp | Promise<string | RegExp>): Promise<void>;
43+
toThrowError(expected?: new (...args: any[]) => Error | Promise<new (...args: any[]) => Error>, message?: string | RegExp | Promise<string | RegExp>): Promise<void>;
44+
}
45+
46+
function addMatchers(matchers: AsyncCustomMatcherFactories): void;
47+
48+
interface Env {
49+
addMatchers(matchers: AsyncCustomMatcherFactories): void;
50+
}
51+
52+
interface Spec {
53+
addMatchers(matchers: AsyncCustomMatcherFactories): void;
54+
}
55+
56+
interface AsyncCustomMatcherFactories {
57+
[index: string]: AsyncCustomMatcherFactory;
58+
}
59+
60+
interface AsyncCustomMatcherFactory {
61+
(util: MatchersUtil, customEqualityTesters: Array<CustomEqualityTester>): AsyncCustomMatcher;
62+
}
63+
64+
interface AsyncCustomMatcher {
65+
compare<T>(actual: T, expected: T): AsyncCustomMatcherResult;
66+
compare(actual: any, expected: any): AsyncCustomMatcherResult;
67+
}
68+
69+
interface AsyncCustomMatcherResult {
70+
pass: boolean | Promise<boolean>;
71+
message?: string;
72+
}
73+
}

spec/asyncAwaitAdapterSpec.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import {promise as wdpromise, WebElement} from 'selenium-webdriver';
2-
const common = require('./common');
3-
4-
declare function expect(actual: any): any;
5-
declare function describe(description: string, tests: Function): void;
6-
declare function it(description: string, test?: Function, timeout?: number): any;
7-
declare function xit(description: string, test?: Function, timeout?: number): any;
8-
declare function beforeEach(setup: Function): void;
9-
declare function beforeAll(setup: Function): void;
10-
declare function afterEach(setup: Function): void;
11-
declare function afterAll(setup: Function): void;
12-
declare var jasmine;
2+
import {getFakeDriver, getMatchers} from './common.js';
133

144
/**
155
* This file is very similar to adapterSpec.ts, but we use async/await instead
166
* of the WebDriver Control Flow for synchronization. These tests are desgined
177
* to work regardless of if the WebDriver Control Flow is disabled.
188
*/
199

20-
const fakeDriver = common.getFakeDriver();
10+
const fakeDriver = getFakeDriver();
2111

2212
/* jshint esversion: 6 */
2313
describe('webdriverJS Jasmine adapter plain', function() {
@@ -54,7 +44,7 @@ describe('webdriverJS Jasmine adapter', function() {
5444
let beforeEachMsg: string;
5545

5646
beforeEach(function() {
57-
jasmine.addMatchers(common.getMatchers());
47+
jasmine.addMatchers(getMatchers());
5848
});
5949

6050
beforeEach(async function() {

spec/asyncAwaitErrorSpec.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
1-
const common = require('./common');
2-
3-
declare function expect(actual: any): any;
4-
declare function describe(description: string, tests: Function): void;
5-
declare function it(description: string, test?: Function, timeout?: number): any;
6-
declare function xit(description: string, test?: Function, timeout?: number): any;
7-
declare function beforeEach(setup: Function): void;
8-
declare function beforeAll(setup: Function): void;
9-
declare function afterEach(setup: Function): void;
10-
declare function afterAll(setup: Function): void;
11-
declare var jasmine;
1+
import {getFakeDriver, getMatchers} from './common.js';
122

133
/**
144
* This file is very similar to errorSpec.ts, but we use async/await instead of
155
* the WebDriver Control Flow for synchronization. These tests are desgined to
166
* work regardless of if the WebDriver Control Flow is disabled.
177
*/
188

19-
const fakeDriver = common.getFakeDriver();
9+
const fakeDriver = getFakeDriver();
2010

2111
/* jshint esversion: 6 */
2212
describe('Timeout cases', function() {
@@ -38,7 +28,7 @@ describe('Timeout cases', function() {
3828

3929
describe('things that should fail', function() {
4030
beforeEach(function() {
41-
jasmine.addMatchers(common.getMatchers());
31+
jasmine.addMatchers(getMatchers());
4232
});
4333

4434
it('should pass errors from done callback', function(done) {
Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,110 @@
1-
var webdriver = require('selenium-webdriver');
1+
import {promise as wdpromise, WebElement} from 'selenium-webdriver';
22

3-
var flow = webdriver.promise.controlFlow();
3+
const flow = wdpromise.controlFlow();
44
require('../index.js').init(flow);
55

6-
exports.getFakeDriver = function() {
6+
export function getFakeDriver() {
77
return {
88
controlFlow: function() {
99
return flow;
1010
},
11-
sleep: function(ms) {
11+
sleep: function(ms: number) {
1212
return flow.timeout(ms);
1313
},
1414
setUp: function() {
1515
return flow.execute(function() {
16-
return webdriver.promise.when('setup done');
16+
return wdpromise.when('setup done');
1717
}, 'setUp');
1818
},
1919
getValueA: function() {
2020
return flow.execute(function() {
21-
return webdriver.promise.delayed(500).then(function() {
22-
return webdriver.promise.when('a');
21+
return wdpromise.delayed(500).then(function() {
22+
return wdpromise.when('a');
2323
});
2424
}, 'getValueA');
2525
},
2626
getOtherValueA: function() {
2727
return flow.execute(function() {
28-
return webdriver.promise.when('a');
28+
return wdpromise.when('a');
2929
}, 'getOtherValueA');
3030
},
3131
getValueB: function() {
3232
return flow.execute(function() {
33-
return webdriver.promise.when('b');
33+
return wdpromise.when('b');
3434
}, 'getValueB');
3535
},
36-
getBigNumber: function() {
36+
getBigNumber: function(): wdpromise.Promise<number> {
3737
return flow.execute(function() {
38-
return webdriver.promise.when(1111);
38+
return wdpromise.when(1111);
3939
}, 'getBigNumber');
4040
},
41-
getSmallNumber: function() {
41+
getSmallNumber: function(): wdpromise.Promise<number> {
4242
return flow.execute(function() {
43-
return webdriver.promise.when(11);
43+
return wdpromise.when(11);
4444
}, 'getSmallNumber');
4545
},
46-
getDecimalNumber: function() {
46+
getDecimalNumber: function(): wdpromise.Promise<number> {
4747
return flow.execute(function() {
48-
return webdriver.promise.when(3.14159);
48+
return wdpromise.when(3.14159);
4949
}, 'getDecimalNumber');
5050
},
5151
getDisplayedElement: function() {
5252
return flow.execute(function() {
53-
return webdriver.promise.when({
53+
return wdpromise.when({
5454
isDisplayed: function() {
55-
return webdriver.promise.when(true);
55+
return wdpromise.when(true);
5656
}
5757
});
5858
}, 'getDisplayedElement');
5959
},
6060
getHiddenElement: function() {
6161
return flow.execute(function() {
62-
return webdriver.promise.when({
62+
return wdpromise.when({
6363
isDisplayed: function() {
64-
return webdriver.promise.when(false);
64+
return wdpromise.when(false);
6565
}
6666
});
6767
}, 'getHiddenElement');
6868
},
69-
getValueList: function() {
69+
getValueList: function(): wdpromise.Promise<Array<{getText: () => wdpromise.Promise<string>}>> {
7070
return flow.execute(function() {
71-
return webdriver.promise.when([{
71+
return wdpromise.when([{
7272
getText: function() {
73-
return flow.execute(function() { return webdriver.promise.when('a');});
73+
return flow.execute(function() { return wdpromise.when('a');});
7474
}
7575
}, {
7676
getText: function() {
77-
return flow.execute(function() { return webdriver.promise.when('b');});
77+
return flow.execute(function() { return wdpromise.when('b');});
7878
}
7979
}, {
8080
getText: function() {
81-
return flow.execute(function() { return webdriver.promise.when('c');});
81+
return flow.execute(function() { return wdpromise.when('c');});
8282
}
8383
}, {
8484
getText: function() {
85-
return flow.execute(function() { return webdriver.promise.when('d');});
85+
return flow.execute(function() { return wdpromise.when('d');});
8686
}
8787
}]);
8888
}, 'getValueList');
8989
},
9090
displayedElement: {
9191
isDisplayed: function() {
92-
return webdriver.promise.when(true);
92+
return wdpromise.when(true);
9393
}
9494
},
9595
hiddenElement: {
9696
isDisplayed: function() {
97-
return webdriver.promise.when(false);
97+
return wdpromise.when(false);
9898
}
9999
}
100100
};
101101
};
102102

103-
exports.getMatchers = function() {
103+
export function getMatchers() {
104104
return {
105105
toBeLotsMoreThan: function() {
106106
return {
107-
compare: function(actual, expected) {
107+
compare: function(actual: number, expected: number) {
108108
return {
109109
pass: actual > expected + 100
110110
};
@@ -114,7 +114,7 @@ exports.getMatchers = function() {
114114
// Example custom matcher returning a promise that resolves to true/false.
115115
toBeDisplayed: function() {
116116
return {
117-
compare: function(actual, expected) {
117+
compare: function(actual: WebElement, expected: void) {
118118
return {
119119
pass: actual.isDisplayed()
120120
};
@@ -124,6 +124,17 @@ exports.getMatchers = function() {
124124
};
125125
};
126126

127-
exports.isPending = function(managedPromise) {
128-
return managedPromise.state_ === 'pending';
127+
// declare custom matcher types
128+
declare global {
129+
namespace jasmine {
130+
interface Matchers {
131+
toBeLotsMoreThan(expected: number | Promise<number>): Promise<void>;
132+
toBeDisplayed(): Promise<void>;
133+
}
134+
}
135+
}
136+
137+
138+
export function isPending(managedPromise: wdpromise.Promise<any>) {
139+
return (managedPromise as any).state_ === 'pending';
129140
};

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"sourceMap": false,
77
"declaration": false,
88
"removeComments": false,
9-
"noImplicitAny": false,
9+
"noImplicitAny": true,
1010
"outDir": "built_spec"
1111
},
1212
"include": [

0 commit comments

Comments
 (0)