-
Notifications
You must be signed in to change notification settings - Fork 41
/
index.bs
11597 lines (8198 loc) · 382 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class=metadata>
Title: WebDriver BiDi
Shortname: webdriver-bidi
Level: None
Status: ED
Group: browser-testing-tools
URL: https://w3c.github.io/webdriver-bidi/
TR: https://www.w3.org/TR/webdriver-bidi/
Repository: w3c/webdriver-bidi
Editor: James Graham, Mozilla https://www.mozilla.org, w3cid 40334
Editor: Alex Rudenko, Google https://www.google.com, w3cid 141088
Editor: Maksim Sadym, Google https://www.google.com, w3cid 128970
Abstract: This document defines the BiDirectional WebDriver Protocol, a mechanism for remote control of user agents.
Boilerplate: conformance no
Complain About: accidental-2119 yes, missing-example-ids yes
Default Ref Status: current
Indent: 2
Implementation Report: https://wpt.fyi/results/webdriver/tests/bidi
Test Suite: https://github.com/web-platform-tests/wpt/tree/master/webdriver/tests/bidi
!Channel: <a href="https://www.w3.org/wiki/IRC">#webdriver on irc.w3.org</a>
!Wiki: <a href="https://www.w3.org/wiki/WebDriver">W3C WebDriver Wiki</a>
</pre>
<pre class=anchors>
spec: RFC6455; urlPrefix: https://datatracker.ietf.org/doc/html/rfc6455
type: dfn
text: WebSocket URI; url: section-3
text: Establishes a WebSocket Connection; url: section-4.1
text: Server-Side Requirements; url: section-4.2
text: Reading the Client's Opening Handshake; url: section-4.2.1
text: %x1 denotes a text frame; url: section-5.2
text: Send a WebSocket Message; url: section-6.1
text: A WebSocket Message Has Been Received; url: section-6.2
text: Start The WebSocket Closing Handshake; url: section-7.1.2
text: The WebSocket Closing Handshake is Started; url: section-7.1.3
text: The WebSocket Connection is Closed; url: section-7.1.4
text: Fail the WebSocket Connection; url: section-7.1.7
text: Status Codes; url: section-7.4
text: Handling Errors in UTF-8-Encoded Data; url: section-8.1
spec: RFC8610; urlPrefix: https://datatracker.ietf.org/doc/html/rfc8610
type: dfn
text: match a CDDL specification; url: appendix-C
spec: RFC6265
type: dfn
text: Cookie; url: https://httpwg.org/specs/rfc6265.html
text: Cookie store; url: https://httpwg.org/specs/rfc6265.html#storage-model
spec: RFC6265bis; urlPrefix: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-05
type: dfn
text: Lax; url: section-4.1.2.7
text: Strict; url: section-4.1.2.7
spec: WEBDRIVER; urlPrefix: https://w3c.github.io/webdriver/
type: dfn
text: WebDriver new session algorithm; url: dfn-webdriver-new-session-algorithms
text: actions; url: actions
text: actions options; url: dfn-actions-options
text: active sessions; url: dfn-active-sessions
text: additional WebDriver capability; url: dfn-additional-webdriver-capability
text: additional capability deserialization algorithm; url: dfn-additional-capability-deserialization-algorithm
text: capability name; url: dfn-capability-name
text: close the session; url: dfn-close-the-session
text: cookie domain; url: dfn-cookie-domain
text: cookie expiry time; url: dfn-cookie-expiry-time
text: cookie HTTP only; url: dfn-cookie-http-only
text: cookie name; url: dfn-cookie-name
text: cookie path; url: dfn-cookie-path
text: cookie same site; url: dfn-cookie-same-site
text: cookie secure only; url: dfn-cookie-secure-only
text: cookie value; url: dfn-cookie-value
text: create a cookie; url: dfn-creating-a-cookie
text: create a session; url: dfn-create-a-session
text: dispatch actions; url: dfn-dispatch-actions
text: dispatch tick actions; url: dfn-dispatch-tick-actions
text: draw a bounding box from the framebuffer; url: dfn-draw-a-bounding-box-from-the-framebuffer
text: endpoint node; url: dfn-endpoint-node
text: error code; url: dfn-error-code
text: error; url: errors
text: extract an action sequence; url: dfn-extract-an-action-sequence
text: get a node; url: dfn-get-a-node
text: get element origin; url: dfn-get-element-origin
text: get or create a node reference; url: dfn-get-or-create-a-node-reference
text: get the input state; url: dfn-get-the-input-state
text: getting a property; url: dfn-getting-properties
text: http session; url: dfn-http-session
text: input cancel list; url: dfn-input-cancel-list
text: intermediary node; url: dfn-intermediary-nodes
text: invalid argument; url: dfn-invalid-argument
text: invalid selector; url: dfn-invalid-selector
text: invalid session id; url: dfn-invalid-session-id
text: is element origin; url: dfn-is-element-origin
text: local end; url: dfn-local-ends
text: matched capability serialization algorithm; url: dfn-matched-capability-serialization-algorithm
text: maximum active sessions; url: dfn-maximum-active-sessions
text: no such alert; url: dfn-no-such-alert
text: no such element; url: dfn-no-such-element
text: no such frame; url: dfn-no-such-frame
text: parse a page range; url: dfn-parse-a-page-range
text: handler; for: prompt handler configuration; url: dfn-handler
text: process capabilities; url: dfn-capabilities-processing
text: readiness state; url: dfn-readiness-state
text: remote end steps; url: dfn-remote-end-steps
text: remote end; url: dfn-remote-ends
text: reset the input state; url: dfn-reset-the-input-state
text: scroll into view; url: dfn-scrolls-into-view
text: session ID; url: dfn-session-id
text: session not created; url: dfn-session-not-created
text: session; url: dfn-sessions
text: set a property; url: dfn-set-a-property
text: success; url: dfn-success
text: table for cookie conversion; url: dfn-table-for-cookie-conversion
text: try; url: dfn-try
text: trying; url: dfn-try
text: unable to capture screen; url: dfn-unable-to-capture-screen
text: unknown command; url: dfn-unknown-command
text: unknown error; url: dfn-unknown-error
text: unsupported operation; url: dfn-unsupported-operation
text: web element reference; url: dfn-web-element-reference
text: webdriver-active flag; url: dfn-webdriver-active-flag
text: window handle; url: dfn-window-handles
spec: CONSOLE; urlPrefix: https://console.spec.whatwg.org
type: dfn
text: formatter; url: formatter
text: formatting specifier; url: formatting-specifiers
text: printer; url: printer
spec: ECMASCRIPT; urlPrefix: https://tc39.es/ecma262/
type: dfn
text: Array; url: sec-array-objects
text: Await; url: await
text: BigInt; url: sec-bigint-constructor
text: Call; url: sec-call
text: Completion Record; url: sec-completion-record-specification-type
text: Construct; url: sec-construct
text: CreateArrayFromList; url: sec-createarrayfromlist
text: CreateArrayIterator; url: sec-createarrayiterator
text: CreateBuiltinFunction; url: sec-createbuiltinfunction
text: CreateListFromArrayLike; url: sec-createlistfromarraylike
text: CreateMapIterator; url: sec-createmapiterator
text: CreateSetIterator; url: sec-createsetiterator
text: Date Time String Format; url: sec-date-time-string-format
text: Date.prototype.toISOString; url: sec-date.prototype.toisostring
text: Date; url: sec-date-constructor
text: EnumerableOwnPropertyNames; url: sec-enumerableownpropertynames
text: Get; url: sec-get-o-p
text: GetIterator; url: sec-getiterator
text: HasProperty; url: sec-hasproperty
text: IsArray; url: sec-isarray
text: IsCallable; url: sec-iscallable
text: IsPromise; url: sec-ispromise
text: IsRegExp; url: sec-isregexp
text: IteratorToList; url: sec-iteratortolist
text: LengthOfArrayLike; url: sec-lengthofarraylike
text: Map; url: #sec-map-iterable; for: constructor
text: Number; url: sec-number-constructor
text: Object.fromEntries; url: sec-object.fromentries
text: Object; url: sec-object-objects
text: RegExp; url: sec-regexp-pattern-flags
text: ScriptEvaluation; url: sec-runtime-semantics-scriptevaluation
text: Set object; url: sec-set-objects
text: String; url: sec-string-constructor
text: StringToBigInt; url: sec-stringtobigint
text: StringToNumber; url: sec-stringtonumber
text: ToString; url: sec-tostring
text: Type; url: sec-ecmascript-data-types-and-values
text: abrupt completion; url: sec-completion-record-specification-type
text: boolean; url: sec-terms-and-definitions-boolean-value
text: current realm record; url: current-realm
text: internal slot; url: sec-object-internal-methods-and-internal-slots
text: null; url: sec-null-value
text: primitive ECMAScript value; url: sec-primitive-value
text: realm; url: sec-code-realms
text: running execution context; url: running-execution-context
text: throw completion; url: sec-completion-record-specification-type
text: test; url: #sec-regexp.prototype.test
text: time value; url: sec-time-values-and-time-range
text: undefined; url: sec-undefined-value
spec: GEOMETRY; urlPrefix: https://drafts.fxtf.org/geometry/
type: dfn
text: rectangle; url: rectangle
text: x coordinate; url: rectangle-x-coordinate
text: y coordinate; url: rectangle-y-coordinate
text: width dimension; url: rectangle-width-dimension
text: height dimension; url: rectangle-height-dimension
spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/
type: dfn
text: 2D context creation algorithm; url: canvas.html#2d-context-creation-algorithm
text: 2D; url: canvas.html#concept-canvas-2d
text: a serialization of the bitmap as a file; url: canvas.html#a-serialisation-of-the-bitmap-as-a-file
text: activation notification; url: interaction.html#activation-notification
text: active window; url: document-sequences.html#nav-window
text: alert; url: timers-and-user-prompts.html#dom-alert
text: close; url: document-sequences.html#close-a-top-level-traversable
text: disabled; url: form-control-infrastructure.html#concept-fe-disabled
text: File Upload state; url: input.html#file-upload-state-(type=file)
text: confirm; url: timers-and-user-prompts.html#dom-confirm
text: context mode; url: /canvas.html#offscreencanvas-context-mode
text: create a classic script; url: webappapis.html#creating-a-classic-script
text: create a new browsing context; url: browsers.html#creating-a-new-browsing-context
text: create a new top-level traversable; url: document-sequences.html#creating-a-new-top-level-traversable
text: default script fetch options; url: webappapis.html#default-script-fetch-options
text: default view; url: nav-history-apis.html#dom-document-defaultview
text: descendant navigables; url: document-sequences.html#descendant-navigables
text: environment settings object's Realm; url: webappapis.html#environment-settings-object's-realm
text: focused area of the document; url: interaction.html#focused-area-of-the-document
text: getting all used history steps; url:browsing-the-web.html#getting-all-used-history-steps
text: hidden; url: document-sequences.html#system-visibility-state
text: history handling behavior; url: browsing-the-web.html#history-handling-behavior
text: innerText getter steps; url:dom.html#dom-innertext
text: input type; url: input.html#dom-input-type
text: navigable; for:window; url: nav-history-apis.html#window-navigable
text: navigables; url: document-sequences.html#navigables
text: navigation id; url: browsing-the-web.html#navigation-id
text: origin-clean; url: canvas.html#concept-canvas-origin-clean
text: parent; for:navigable; url: document-sequences.html#nav-parent
text: prompt to unload; url: browsing-the-web.html#prompt-to-unload-a-document
text: prompt; url: timers-and-user-prompts.html#dom-prompt
text: report an error; url: webappapis.html#report-the-error
text: run the animation frame callbacks; url: imagebitmap-and-animations.html#run-the-animation-frame-callbacks
text: same origin domain; url: browsers.html#same-origin-domain
text: select an image source from a source set; url: images.html#select-an-image-source-from-a-source-set
text: selected files; url: input.html#concept-input-type-file-selected
text: session history entry; url: browsing-the-web.html#session-history-entry
text: session history traversal queue; url: document-sequences.html#tn-session-history-traversal-queue
text: session history; url: history.html#session-history
text: set up a window environment settings object; url: nav-history-apis.html#set-up-a-window-environment-settings-object
text: set up a worker environment settings object; url: workers.html#set-up-a-worker-environment-settings-object
text: set up a worklet environment settings object; url: worklets.html#set-up-a-worklet-environment-settings-object
text: shared worker; url: workers.html#shared-workers
text: system visibility state; url: document-sequences.html#system-visibility-state
text: traversable navigable; url:document-sequences.html#traversable-navigable
text: traverse the history by a delta; url: browsing-the-web.html#traverse-the-history-by-a-delta
text: update the file selection; url: input.html#update-the-file-selection
text: visible; url: document-sequences.html#system-visibility-state
text: worker event loop; url: webappapis.html#worker-event-loop-2
text: worklet global scopes; url:worklets.html#concept-document-worklet-global-scopes
spec: INFRA; urlPrefix: https://infra.spec.whatwg.org/
type: dfn
text: convert a JSON-derived JavaScript value to an Infra value; url: convert-a-json-derived-javascript-value-to-an-infra-value
spec: RESOURCE-TIMING; urlPrefix: https://w3c.github.io/resource-timing/
type: dfn
text: convert fetch timestamp; url: dfn-convert-fetch-timestamp
spec: HR-TIME; urlPrefix: https://w3c.github.io/hr-time/
type: dfn
text: get time origin timestamp; url: dfn-get-time-origin-timestamp
spec: RFC4648; urlPrefix: https://datatracker.ietf.org/doc/html/rfc4648
type: dfn
text: Base64 Encode; url: section-4
spec: CSS-VALUES-3; urlPrefix: https://drafts.csswg.org/css-values-3/
type: dfn
text: absolute lengths; url: #absolute-lengths
spec: CSSOM-VIEW; urlPrefix: https://drafts.csswg.org/cssom-view/
type: dfn
text: CSS pixel; url: #dom-window-devicepixelratio
text: evaluate media queries and report changes; url: #evaluate-media-queries-and-report-changes
text: layout viewport; url: #layout-viewport
text: scroll height; url: #dom-element-scrollheight
text: scroll width; url: #dom-element-scrollwidth
text: visual viewport page left; url: #dom-visualviewport-pageleft
text: visual viewport page top; url: #dom-visualviewport-pagetop
text: visual viewport; url: #visual-viewport
text: web-exposed screen area; url: #web-exposed-screen-area
spec: DOM; urlPrefix: https://dom.spec.whatwg.org/
type: dfn
text: root; url: #concept-tree-root
text: document element; url: #ref-for-dom-document-documentelement
text: evaluate; url: #dom-xpathevaluatorbase-evaluate
text: ORDERED_NODE_SNAPSHOT_TYPE; url: #dom-xpathresult-ordered_node_snapshot_type
text: snapshotItem; url: #dom-xpathresult-snapshotitem
spec: FULLSCREEN; urlPrefix: https://fullscreen.spec.whatwg.org/
type: dfn
text: fullscreen an element; url: #fullscreen-an-element
text: fullscreen is supported; url: #fullscreen-is-supported
text: fully exit fullscreen; url: #fully-exit-fullscreen
spec: SELECTORS4; urlPrefix: https://drafts.csswg.org/selectors-4/
type: dfn
text: match a selector against a tree; url: #match-a-selector-against-a-tree
text: parse a selector; url: #parse-a-selector
text: scoping root; url: #scoping-root
spec: WEB-IDL; urlPrefix: https://webidl.spec.whatwg.org/
type: dfn
text: DOMException; url: #idl-DOMException
text: SyntaxError; url:#syntaxerror
spec: UNICODE; urlPrefix: https://www.unicode.org/versions/Unicode15.0.0/
type: dfn
text: Unicode Default Case Conversion algorithm; url: ch03.pdf#G34944
text: toUppercase; url: ch03.pdf#G34078
spec: ACCNAME; urlPrefix:https://www.w3.org/TR/accname-1.2
type: dfn
text: accessible name; url: /#dfn-accessible-name
spec: CORE-AAM; urlPrefix:https://www.w3.org/TR/core-aam-1.2
type: dfn
text: computed role; url: /#roleMappingComputedRole
spec: MEDIAQUERIES4; urlPrefix: https://drafts.csswg.org/mediaqueries-4/
type: dfn
text: resolution media feature; url: #resolution
spec: RFC9110; urlPrefix: https://httpwg.org/specs/rfc9110.html
type: dfn
text: field-name token; url: #fields.names
text: method token; url: #method.overview
</pre>
<pre class="biblio">
{
"SAME-SITE-COOKIES": {
"authors": ["Mike West", "Mark Goodwin"],
"href": "https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-same-site",
"publisher": "IETF",
"title": "Same-Site Cookies"
}
}
</pre>
<style>
var {
color: #cd5c5c
}
/**
* Emulate the appearace of the so-called "simple" table provided by ReSpec, as
* used in WebDriver Classic.
*/
table.respec-simple {
border-spacing: 0;
border-collapse: collapse;
border-bottom: 3px solid #005a9c;
}
table.respec-simple th {
background: #005a9c;
color: #fff;
padding: 3px 5px;
text-align: left;
}
table.respec-simple tr:nth-child(2n) {
background: #f0f6ff;
}
table.respec-simple td {
padding: 3px 10px;
border-top: 1px solid #ddd;
}
</style>
# Introduction # {#intro}
<em>This section is non-normative.</em>
[[WEBDRIVER|WebDriver]] defines a protocol for introspection and
remote control of user agents. This specification extends WebDriver by
introducing bidirectional communication. In place of the strict
command/response format of WebDriver, this permits events to stream
from the user agent to the controlling software, better matching the
evented nature of the browser DOM.
# Infrastructure # {#infrastructure}
This specification depends on the Infra Standard. [[!INFRA]]
Network protocol messages are defined using CDDL. [[!RFC8610]]
This specification defines a <dfn>wait queue</dfn> which is a [=/map=].
Issue: Surely there's a better mechanism for doing this "wait for an event" thing.
<div algorithm>
When an algorithm |algorithm| running [=in parallel=] <dfn export>awaits</dfn> a set of
events |events|, and |resume id|:
1. Pause the execution of |algorithm|.
1. Assert: [=wait queue=] does not contain |resume id|.
1. Set [=wait queue=][|resume id|] to (|events|, |algorithm|).
</div>
<div algorithm>
To <dfn export>resume</dfn> given |name|, |id| and |parameters|:
1. If [=wait queue=] does not contain |id|, return.
1. Let (|events|, |algorithm|) be [=wait queue=][|id|]
1. For each |event| in |events|:
1. If |event| equals |name|:
1. Remove |id| from [=wait queue=].
1. Resume running the steps in |algorithm| from the
point at which they were paused, passing |name| and |parameters| as the
result of the [=await=].
Issue: Should we have something like microtasks to ensure this runs
before any other tasks on the event loop?
</div>
# Protocol # {#protocol}
This section defines the basic concepts of the WebDriver BiDi
protocol. These terms are distinct from their representation at the
<a href=#transport>transport</a> layer.
The protocol is defined using a [[!RFC8610|CDDL]] definition. For the
convenience of implementers two separate CDDL definitions are defined; the
<dfn export>remote end definition</dfn> which defines the format of messages produced
on the [=local end=] and consumed on the [=remote end=], and the <dfn export>local end
definition</dfn> which defines the format of messages produced on the [=remote end=]
and consumed on the [=local end=]
## Definition ## {#protocol-definition}
Issue: Should this be an appendix?
This section gives the initial contents of the [=remote end definition=] and
[=local end definition=]. These are augmented by the definition fragments defined in
the remainder of the specification.
[=Remote end definition=]
<pre class="cddl remote-cddl">
Command = {
id: js-uint,
CommandData,
Extensible,
}
CommandData = (
BrowserCommand //
BrowsingContextCommand //
InputCommand //
NetworkCommand //
ScriptCommand //
SessionCommand //
StorageCommand //
WebExtensionCommand
)
EmptyParams = {
Extensible
}
</pre>
[=Local end definition=]
<pre class="cddl local-cddl">
Message = (
CommandResponse /
ErrorResponse /
Event
)
CommandResponse = {
type: "success",
id: js-uint,
result: ResultData,
Extensible
}
ErrorResponse = {
type: "error",
id: js-uint / null,
error: ErrorCode,
message: text,
? stacktrace: text,
Extensible
}
ResultData = (
BrowsingContextResult /
EmptyResult /
NetworkResult /
ScriptResult /
SessionResult /
StorageResult /
WebExtensionResult
)
EmptyResult = {
Extensible
}
Event = {
type: "event",
EventData,
Extensible
}
EventData = (
BrowsingContextEvent //
LogEvent //
NetworkEvent //
ScriptEvent
)
</pre>
[=Remote end definition=] and [=Local end definition=]
<pre class="cddl remote-cddl local-cddl">
Extensible = (*text => any)
js-int = -9007199254740991..9007199254740991
js-uint = 0..9007199254740991
</pre>
## Session ## {#session}
WebDriver BiDi extends the [=/session=] concept from [[WEBDRIVER|WebDriver]].
A [=/session=] has a <dfn>BiDi flag</dfn>, which is false unless otherwise
stated.
A <dfn export>BiDi session</dfn> is a [=/session=] which has the [=BiDi flag=]
set to true.
<div algorithm>
The list of <dfn export>active BiDi sessions</dfn> is given by:
1. Let |BiDi sessions| be a new [=/list=].
1. For each |session| in [=active sessions=]:
1. If |session| is a [=BiDi session=] append |session| to |BiDi sessions|.
1. Return |BiDi sessions|.
</div>
## Modules ## {#protocol-modules}
The WebDriver BiDi protocol is organized into modules.
Each <dfn export>module</dfn> represents a collection of related
[=commands=] and [=events=] pertaining to a certain aspect of the user
agent. For example, a module might contain functionality for inspecting and
manipulating the DOM, or for script execution.
Each module has a <dfn for=module export>module name</dfn> which is a string. The
[=command name=] and [=event name=] for commands and events defined in the
module start with the [=module name=] followed by a period "<code>.</code>".
Modules which contain [=commands=] define [=remote end definition=]
fragments. These provide choices in the <code>CommandData</code> group for the
module's [=commands=], and can also define additional definition properties. They
can also define [=local end definition=] fragments that provide additional choices
in the <code>ResultData</code> group for the results of commands in the module.
Modules which contain events define [=local end definition=] fragments that are
choices in the <code>Event</code> group for the module's [=events=].
An implementation may define <dfn export>extension modules</dfn>. These must have a
[=module name=] that contains a single colon "<code>:</code>" character. The
part before the colon is the prefix; this is typically the same for all
[=extension modules=] specific to a given implementation and should be unique for a
given implementation.
Other specifications may define their own WebDriver-BiDi modules that extend the protocol.
Such modules must not have a name which contains a colon (<code>:</code>) character,
nor must they define [=command names=], [=event names=], or property names that contain that character.
Authors of external specifications are encouraged to to add new modules rather than extending
existing ones. Where it is desired to extend an existing module, it is preferred to integrate the
extension directly into the specification containing the original module definition.
## Commands ## {#commands}
A <dfn export>command</dfn> is an asynchronous operation, requested by
the [=local end=] and run on the [=remote end=], resulting in either a
result or an error being returned to the [=local end=]. Multiple
commands can run at the same time, and commands can potentially be
long-running. As a consequence, commands can finish out-of-order.
Each [=command=] is defined by:
- A <dfn export for=command>command type</dfn> which is defined by a [=remote end definition=]
fragment containing a group. Each such group has two fields:
- <code>method</code> which is a string literal of the form <code>[module
name].[method name]</code>. This is the <dfn export for=command>command
name</dfn>.
- <code>params</code> which defines a mapping containing data that to be passed into
the command. The populated value of this map is the
<dfn export for=command>command parameters</dfn>.
- A <dfn export for=command>result type</dfn>, which is defined by a [=local
end definition=] fragment.
- A set of [=remote end steps=] which define the actions to take for a command
given a [=BiDi session=] and [=command parameters=] and return an
instance of the command [=result type=].
A command that can run without an active session is a <dfn export>static
command</dfn>. Commands are not static commands unless stated in their
definition.
When commands are sent from the [=local end=] they have a command id. This is an
identifier used by the [=local end=] to identify the response from a particular
command. From the point of view of the [=remote end=] this identifier is opaque
and cannot be used internally to identify the command.
Note: This is because the command id is entirely controlled by the [=local end=]
and isn't necessarily unique over the course of a session. For example a [=local
end=] which ignores all responses could use the same command id for each command.
The <dfn export>set of all command names</dfn> is a [=/set=] containing
all the defined [=command names=], including any belonging to [=extension
modules=].
## Errors ## {#errors}
WebDriver BiDi extends the set of [=error codes=] from [[WEBDRIVER|WebDriver]]
with the following additional codes:
<dl>
<dt><dfn for=errors export>invalid web extension</dfn>
<dd>Tried to install an invalid web extension.
<dt><dfn for=errors export>no such client window</dfn>
<dd>Tried to interact with an unknown [=client window=].
<dt><dfn for=errors export>no such handle</dfn>
<dd>Tried to deserialize an unknown <code>RemoteObjectReference</code>.
<dt><dfn for=errors export>no such history entry</dfn>
<dd>Tried to havigate to an unknown [=session history entry=].
<dt><dfn for=errors export>no such intercept</dfn>
<dd>Tried to remove an unknown [=network intercept=].
<dt><dfn for=errors export>no such node</dfn>
<dd>Tried to deserialize an unknown <code>SharedReference</code>.
<dt><dfn for=errors export>no such request</dfn>
<dd>Tried to continue an unknown [=/request=].
<dt><dfn for=errors export>no such script</dfn>
<dd>Tried to remove an unknown [=preload script=].
<dt><dfn for=errors export>no such storage partition</dfn>
<dd>Tried to access data in a non-existent storage partition.
<dt><dfn for=errors export>no such user context</dfn>
<dd>Tried to reference an unknown [=user context=].
<dt><dfn for=errors export>no such web extension</dfn>
<dd>Tried to reference an unknown web extension.
<dt><dfn for=errors export>unable to close browser</dfn>
<dd>Tried to close the browser, but failed to do so.
<dt><dfn for=errors export>unable to set cookie</dfn>
<dd>Tried to create a cookie, but the user agent rejected it.
<dt><dfn for=errors export>underspecified storage partition</dfn>
<dd>Tried to interact with data in a storage partition which was not adequately specified.
<dt><dfn for=errors export>unable to set file input</dfn>
<dd>Tried to set a file input, but failed to do so.
</dl>
<pre class="cddl local-cddl">
ErrorCode = "invalid argument" /
"invalid selector" /
"invalid session id" /
"invalid web extension" /
"move target out of bounds" /
"no such alert" /
"no such element" /
"no such frame" /
"no such handle" /
"no such history entry" /
"no such intercept" /
"no such node" /
"no such request" /
"no such script" /
"no such storage partition" /
"no such user context" /
"no such web extension" /
"session not created" /
"unable to capture screen" /
"unable to close browser" /
"unable to set cookie" /
"unable to set file input" /
"underspecified storage partition" /
"unknown command" /
"unknown error" /
"unsupported operation"
</pre>
## Events ## {#events}
An <dfn export>event</dfn> is a notification, sent by the [=remote end=]
to the [=local end=], signaling that something of interest has
occurred on the [=remote end=].
- An <dfn export for=event>event type</dfn> is defined by a [=local
end definition=] fragment containing a group. Each such group has two fields:
- <code>method</code> which is a string literal of the form <code>[module
name].[event name]</code>. This is the <dfn export for=event>event
name</dfn>.
- <code>params</code> which defines a mapping containing event data. The
populated value of this map is the <dfn export for=event>event
parameters</code>.
- A <dfn for=event export>remote end event trigger</dfn> which defines when the
event is triggered and steps to construct the [=event type=] data.
- Optionally, a set of <dfn for=event export>remote end subscribe steps</dfn>,
which define steps to take when a local end subscribes to an event. Where
defined these steps have an associated <dfn for=event export>subscribe
priority</dfn> which is an integer controlling the order in which the steps
are run when multiple events are enabled at once, with lower integers
indicating steps that run earlier.
A [=BiDi session=] has a <dfn export for=event>global event set</dfn>
which is a [=/set=] containing the event names for events that are enabled for all
navigables. This initially contains the [=event name=] for events that
are <dfn export for=event>in the default event set</dfn>.
A [=BiDi session=] has a <dfn export for=event>navigable event map</dfn>,
which is a [=/map=] with [=/top-level traversable=] keys and values
that are a [=/set=] of [=event name=]s for events that are enabled in the given
navigable.
<div algorithm>
To obtain a list of <dfn>event enabled navigables</dfn> given
|session| and |event name|:
1. Let |navigables| be an empty [=/set=].
1. For each |navigable| → |events| of |session|'s [=navigable event map=]:
1. If |events| contains |event name|, append |navigable| to |navigables|
1. Return |navigables|.
</div>
<div algorithm>
The <dfn export>set of sessions for which an event is enabled</dfn> given |event
name| and |navigables| is:
1. Let |sessions| be a new [=/set=].
1. For each |session| in [=active BiDI sessions=]:
1. If [=event is enabled=] with |session|, |event name| and |navigables|,
append |session| to |sessions|.
1. Return |sessions|.
</div>
<div algorithm>
To determine if an <dfn export>event is enabled</dfn> given |session|,
|event name| and |navigables|:
Note: |navigables| is a set because a [=shared worker=] can be associated
with multiple contexts.
1. Let |top-level traversables| be an empty [=/set=].
1. For each |navigable| of |navigables|, append |navigable|'s [=navigable/top-level traversable=] to |top-level traversables|.
1. Let |event map| be the [=navigable event map=] for |session|.
1. For each |navigable| of |top-level traversables|:
1. If |event map| [=map/contains=] |navigable|, let |navigable events|
be |event map|[|navigable|]. Otherwise let |navigable events| be null.
1. If |navigable events| is not null, and |navigable events|
[=list/contains=] |event name|, return true.
1. If the [=global event set=] for |session| [=list/contains=] |event name| return
true.
1. Return false.
</div>
<div algorithm>
To <dfn>obtain a set of event names</dfn> given an |name|:
1. Let |events| be an empty [=/set=].
1. If |name| contains a U+002E (period):
1. If |name| is the [=event name=] for an event, append |name| to |events|
and return [=success=] with data |events|.
1. Return an [=error=] with [=error code=] [=invalid argument=]
1. Otherwise |name| is interpreted as representing all the events in a
module. If |name| is not a [=module name=] return an [=error=] with
[=error code=] [=invalid argument=].
1. Append the [=event name=] for each [=event=] in the module with name |name| to
|events|.
1. Return [=success=] with data |events|.
</div>
# Transport # {#transport}
Message transport is provided using the WebSocket protocol.
[[!RFC6455]]
Note: In the terms of the WebSocket protocol, the [=local end=] is the
client and the [=remote end=] is the server / remote host.
Note: The encoding of [=commands=] and [=events=] as messages is
similar to JSON-RPC, but this specification does not normatively
reference it. [[JSON-RPC]] The normative requirements on [=remote ends=]
are instead given as a precise processing model, while no
normative requirements are given for [=local ends=].
A <dfn>WebSocket listener</dfn> is a network endpoint that is able
to accept incoming [[!RFC6455|WebSocket]] connections.
A [=WebSocket listener=] has a <dfn for=listener>host</dfn>, a <dfn
for=listener>port</dfn>, a <dfn for=listener>secure flag</dfn>, and a
<dfn>list of WebSocket resources</dfn>.
When a [=WebSocket listener=] |listener| is created, a [=remote end=]
must start to listen for WebSocket connections on the host and port
given by |listener|'s [=listener/host=] and [=listener/port=]. If
|listener|'s [=listener/secure flag=] is set, then connections
established from |listener| must be TLS encrypted.
A [=remote end=] has a [=/set=] of [=WebSocket listeners=] <dfn>active
listeners</dfn>, which is initially empty.
A [=remote end=] has a [=/set=] of <dfn>WebSocket connections not associated with a
session</dfn>, which is initially empty.
A <dfn>WebSocket connection</dfn> is a network connection that follows the
requirements of the [[!RFC6455|WebSocket protocol]]
A [=BiDi session=] has a [=/set=] of <dfn>session WebSocket
connections</dfn> whose elements are [=WebSocket connections=]. This is
initially empty.
A [=BiDi session=] |session| is <dfn>associated with connection</dfn>
|connection| if |session|'s [=session WebSocket connections=] contains |connection|.
Note: Each [=WebSocket connection=] is associated with at most one [=BiDi
session=].
<div>
When a client [=establishes a WebSocket connection=] |connection| by
connecting to one of the set of [=active listeners=] |listener|, the
implementation must proceed according to the WebSocket [=server-side
requirements=], with the following steps run when deciding whether to
accept the incoming connection:
1. Let |resource name| be the resource name from [=reading the
client's opening handshake=]. If |resource name| is not in
|listener|'s [=list of WebSocket resources=], then stop
running these steps and act as if the requested service is not
available.
1. If |resource name| is the byte string "<code>/session</code>",
and the implementation [=supports BiDi-only sessions=]:
1. Run any other implementation-defined steps to decide if the
connection should be accepted, and if it is not stop running these
steps and act as if the requested service is not available.
1. Add the connection to [=WebSocket connections not associated with a
session=].
1. Return.
1. [=Get a session ID for a WebSocket resource=] with |resource name|
and let |session id| be that value. If |session id| is null then
stop running these steps and act as if the requested service is not
available.
1. If there is a [=/session=] in the list of [=active sessions=] with
|session id| as its [=session ID=] then let |session| be that
session. Otherwise stop running these steps and act as if the
requested service is not available.
1. Run any other implementation-defined steps to decide if the
connection should be accepted, and if it is not stop running these
steps and act as if the requested service is not available.
1. Otherwise append |connection| to |session|'s [=session WebSocket
connections=], and proceed with the WebSocket [=server-side requirements=]
when a server chooses to accept an incoming connection.
Issue: Do we support > 1 connection for a single session?
</div>
When [=a WebSocket message has been received=] for a [=WebSocket
connection=] |connection| with type |type| and data |data|, a [=remote end=]
must [=handle an incoming message=] given |connection|, |type| and |data|.
When [=the WebSocket closing handshake is started=] or when [=the
WebSocket connection is closed=] for a [=WebSocket connection=]
|connection|, a [=remote end=] must [=handle a connection closing=]
given |connection|.
Note: Both conditions are needed because it is possible for a
WebSocket connection to be closed without a closing handshake.
<div algorithm>
To <dfn>construct a WebSocket resource name</dfn>
given a [=/session=] |session|:
1. If |session| is null, return "<code>/session</code>"
1. Return the result of concatenating the string "<code>/session/</code>"
with |session|'s [=session ID=].
</div>
<div algorithm>
To <dfn>construct a WebSocket URL</dfn> given a [=WebSocket listener=]
|listener| and [=/session=] |session|:
1. Let |resource name| be the result of [=construct a WebSocket
resource name=] with |session|.
1. Return a [=WebSocket URI=] constructed with host set to
|listener|'s [=listener/host=], port set to |listener|'s
[=listener/port=], path set to |resource name|, following the wss-URI
construct if |listener|'s [=listener/secure flag=] is set and the ws-URL
construct otherwise.
</div>
<div algorithm>
To <dfn>get a session ID for a WebSocket resource</dfn>
given |resource name|:
1. If |resource name| doesn't begin with the byte string
"<code>/session/</code>", return null.
1. Let |session id| be the bytes in |resource name| following the
"<code>/session/</code>" prefix.
1. If |session id| is not the string representation of a
[[!RFC9562|UUID]], return null.
1. Return |session id|.
</div>
<div algorithm>
To <dfn>start listening for a WebSocket connection</dfn> given a
[=/session=] |session|:
1. If there is an existing [=WebSocket listener=] in [=active listeners=] which
the [=remote end=] would like to reuse, let |listener| be that
listener. Otherwise let |listener| be a new [=WebSocket listener=] with
[=implementation-defined=] [=listener/host=], [=listener/port=],
[=listener/secure flag=], and an empty [=list of WebSocket resources=].
1. Let |resource name| be the result of [=construct a WebSocket
resource name=] with |session|.
1. Append |resource name| to the [=list of WebSocket resources=] for
|listener|.
1. [=set/Append=] |listener| to the [=remote end=]'s [=active
listeners=].
1. Return |listener|.
</div>
Note: An [=intermediary node=] handling multiple sessions can use one
or many WebSocket listeners. [[!WEBDRIVER|WebDriver]] defines that
an [=endpoint node=] supports at most one session at a time, so it's
expected to only have a single listener.
Note: For an [=endpoint node=] the [=listener/host=] in the above steps will
typically be "<code>localhost</code>".
<div algorithm>
To <dfn>handle an incoming message</dfn> given a [=WebSocket connection=]
|connection|, type |type| and data |data|:
1. If |type| is not [=%x1 denotes a text frame|text=], [=send an error
response=] given |connection|, null, and [=invalid argument=], and finally
return.
1. [=Assert=]: |data| is a [=scalar value string=], because the
WebSocket [=handling errors in UTF-8-encoded data=] would already
have [=fail the WebSocket connection|failed the WebSocket
connection=] otherwise.
Issue: Nothing seems to define what [=status codes|status code=]
is used for UTF-8 errors.