UNPKG

4.51 kBPlain TextView Raw
1import {bind, provide, Provider} from 'angular2/src/core/di';
2import {Json, isPresent, isBlank, RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
3import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
4
5import {WebDriverExtension, PerfLogFeatures} from '../web_driver_extension';
6import {WebDriverAdapter} from '../web_driver_adapter';
7
8export class IOsDriverExtension extends WebDriverExtension {
9 // TODO(tbosch): use static values when our transpiler supports them
10 static get BINDINGS(): Provider[] { return _PROVIDERS; }
11
12 constructor(private _driver: WebDriverAdapter) { super(); }
13
14 gc(): Promise<any> { throw new BaseException('Force GC is not supported on iOS'); }
15
16 timeBegin(name: string): Promise<any> {
17 return this._driver.executeScript(`console.time('${name}');`);
18 }
19
20 timeEnd(name: string, restartName: string = null): Promise<any> {
21 var script = `console.timeEnd('${name}');`;
22 if (isPresent(restartName)) {
23 script += `console.time('${restartName}');`
24 }
25 return this._driver.executeScript(script);
26 }
27
28 // See https://github.com/WebKit/webkit/tree/master/Source/WebInspectorUI/Versions
29 readPerfLog() {
30 // TODO(tbosch): Bug in IOsDriver: Need to execute at least one command
31 // so that the browser logs can be read out!
32 return this._driver.executeScript('1+1')
33 .then((_) => this._driver.logs('performance'))
34 .then((entries) => {
35 var records = [];
36 entries.forEach(entry => {
37 var message = Json.parse(entry['message'])['message'];
38 if (StringWrapper.equals(message['method'], 'Timeline.eventRecorded')) {
39 records.push(message['params']['record']);
40 }
41 });
42 return this._convertPerfRecordsToEvents(records);
43 });
44 }
45
46 _convertPerfRecordsToEvents(records: any[], events: any[] = null) {
47 if (isBlank(events)) {
48 events = [];
49 }
50 records.forEach((record) => {
51 var endEvent = null;
52 var type = record['type'];
53 var data = record['data'];
54 var startTime = record['startTime'];
55 var endTime = record['endTime'];
56
57 if (StringWrapper.equals(type, 'FunctionCall') &&
58 (isBlank(data) || !StringWrapper.equals(data['scriptName'], 'InjectedScript'))) {
59 events.push(createStartEvent('script', startTime));
60 endEvent = createEndEvent('script', endTime);
61 } else if (StringWrapper.equals(type, 'Time')) {
62 events.push(createMarkStartEvent(data['message'], startTime));
63 } else if (StringWrapper.equals(type, 'TimeEnd')) {
64 events.push(createMarkEndEvent(data['message'], startTime));
65 } else if (StringWrapper.equals(type, 'RecalculateStyles') ||
66 StringWrapper.equals(type, 'Layout') ||
67 StringWrapper.equals(type, 'UpdateLayerTree') ||
68 StringWrapper.equals(type, 'Paint') || StringWrapper.equals(type, 'Rasterize') ||
69 StringWrapper.equals(type, 'CompositeLayers')) {
70 events.push(createStartEvent('render', startTime));
71 endEvent = createEndEvent('render', endTime);
72 }
73 // Note: ios used to support GCEvent up until iOS 6 :-(
74 if (isPresent(record['children'])) {
75 this._convertPerfRecordsToEvents(record['children'], events);
76 }
77 if (isPresent(endEvent)) {
78 events.push(endEvent);
79 }
80 });
81 return events;
82 }
83
84 perfLogFeatures(): PerfLogFeatures { return new PerfLogFeatures({render: true}); }
85
86 supports(capabilities: {[key: string]: any}): boolean {
87 return StringWrapper.equals(capabilities['browserName'].toLowerCase(), 'safari');
88 }
89}
90
91function createEvent(ph, name, time, args = null) {
92 var result = {
93 'cat': 'timeline',
94 'name': name,
95 'ts': time,
96 'ph': ph,
97 // The ios protocol does not support the notions of multiple processes in
98 // the perflog...
99 'pid': 'pid0'
100 };
101 if (isPresent(args)) {
102 result['args'] = args;
103 }
104 return result;
105}
106
107function createStartEvent(name, time, args = null) {
108 return createEvent('B', name, time, args);
109}
110
111function createEndEvent(name, time, args = null) {
112 return createEvent('E', name, time, args);
113}
114
115function createMarkStartEvent(name, time) {
116 return createEvent('b', name, time);
117}
118
119function createMarkEndEvent(name, time) {
120 return createEvent('e', name, time);
121}
122
123var _PROVIDERS = [
124 bind(IOsDriverExtension)
125 .toFactory((driver) => new IOsDriverExtension(driver), [WebDriverAdapter])
126];