summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/editing/data/README.md
blob: 2ac414b280275ea7a5ad1f376b6fe65d1bb897fe (plain)
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
# editing/data/*.js Format #

In the interests of keeping file size down, the format of these
(machine-generated) data files is relatively concise.  Unfortunately, this
means they can appear slightly cryptic to the untrained eye:

       ["foo[bar]baz",
         [["stylewithcss","false"],["bold",""]],
         "foo<b>[bar]</b>baz",
         [true,true],
         {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

But never fear!  It's not actually so complicated (assuming you understand the
relevant APIs to begin with).  Each line has the following format, which we
will explain in due course:

       ["initial HTML",
         [["command1", "arg1"], ["command2", "arg2"]],
         "expected HTML",
         [expected retval from command1, expected retval from command2],
         {"command1":[expected original/final indeterm/state/value 1],
          "command2":[expected original/final indeterm/state/value 2]}],

## Line 1: Initial HTML ##

    -> ["foo[bar]baz",
         [["stylewithcss","false"],["bold",""]],
         "foo<b>[bar]</b>baz",
         [true,true],
         {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

When testing, first a contenteditable div's innerHTML is set to the value given
here.  Then the characters []{} are located and removed, and the selection is
set to where they used to be, as follows:

  * [ and ] indicate the left or right endpoint of the selection, if it's in
    a text node.
  * { and } indicate the left or right endpoint of the selection, if it's not
    in a text node.

Thus `<b>[foo]</b>` means the selection start and end are (foo, 0) and (foo,
3), while `<b>{foo}</b>` means they're (`<b>`, 0) and (`<b>`, 1).
`<b>[foo}</b>` and `<b>{foo]</b>` are also possible.  There is no way to
describe backwards selections (i.e., distinguish anchor/focus).

In cases where you want the selection in a place where it's not possible to
place text, like `<table><tbody>{<tr></tr>}</tbody></table>`, another format
exists using data-start and data-end attributes.  It's only used in a few
tests, so it is not documented here.

## Line 2: commands ##

       ["foo[bar]baz",
    ->   [["stylewithcss","false"],["bold",""]],
         "foo<b>[bar]</b>baz",
         [true,true],
         {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

After the innerHTML of the editing host is filled in, the commands given here
are run in order, like this:

    document.execCommand("stylewithcss", false, "false");
    document.execCommand("bold", false, "");

Most tests have only one command run.  The exceptions are:

  1. styleWithCSS.  Tests that involve formatting elements or styles are run
     twice, once with styleWithCSS on and once with it off.
  2. defaultParagraphSeparator.  Tests that involve `<p>`s or `<div>`s are run
     twice, once with defaultParagraphSeparator set to "div" and once "p".
  3. multitest.js tests interactions between different commands, so it contains
     arbitrary combinations of commands.

## Line 3: expected HTML ##

       ["foo[bar]baz",
         [["stylewithcss","false"],["bold",""]],
    ->   "foo<b>[bar]</b>baz",
         [true,true],
         {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

After the commands are run, we check that the innerHTML of the editing host
matches the expected HTML provided here.  As on line 1, the characters []{}
(and data-start/data-end attributes) have special meaning and are not really
expected to be in the HTML.  However, on this line they don't affect the test's
processing -- there are no tests of what the final selection is.

This can be array of string if there are some acceptable cases.  However,
array shouldn't be used as far as possible because WPT checks compatibility
between browsers.  So, this should be used when:

- There are some different behaviors in edge cases.
- There are some differences which are not related to the test.

## Line 4: expected return values ##

       ["foo[bar]baz",
         [["stylewithcss","false"],["bold",""]],
         "foo<b>[bar]</b>baz",
    ->   [true,true],
         {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

execCommand() returns a boolean: true if all went well, false if not (e.g.,
invalid value).  This line says what value each execCommand() call from line 2
was supposed to return.  Usually they'll all be true, but for tests of
error-handling they'll sometimes be false.

## Line 5: expected indeterm/state/value ##

       ["foo[bar]baz",
         [["stylewithcss","false"],["bold",""]],
         "foo<b>[bar]</b>baz",
         [true,true],
    ->   {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

For each command that we're running, we check queryCommandIndeterm(),
queryCommandState(), and queryCommandValue() before we begin running any of our
commands, and again after we've finished the last one.  (We don't run these
checks in between commands.)  For each command, this line gives an array of six
expected values, in order:

  1. Indeterm before
  2. State before
  3. Value before
  4. Indeterm after
  5. State after
  6. Value after

You can remember this by keeping in mind that the three "before" values come
before the three "after" values, and each set of three values is in
alphabetical order (indeterm/state/value).

## Analysis of a real-world example ##

Let's look back at the example we started with and see what it means:

    ["foo[bar]baz",
      [["stylewithcss","false"],["bold",""]],
      "foo<b>[bar]</b>baz",
      [true,true],
      {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}],

Line 1: Set the innerHTML of our editing host to `foobarbaz`, and set the
selection's start and end inside the resulting text node, selecting the letters
"bar".  (We actually first set the innerHTML to `foo[bar]baz` and remove the
brackets afterwards.)

Line 2: Execute the commands:

    document.execCommand("stylewithcss", false, "false");
    document.execCommand("bold", false, "");

Before doing this, we record the indeterm/state/value for both "stylewithcss"
and "bold", and afterwards, we record them again.  We also record the return
value of both execCommand() calls.

Line 3: Our new innerHTML should be `foo<b>bar</b>baz`.  The [ and ] say where
we would theoretically want the selection to be, but no actual test is run.

Line 4: Both execCommands we ran should return true.

Line 5: We expect the indeterm for styleWithCSS to be false both before and
after, and the value to be "" before and after -- since they always are for
this command.  The state for styleWithCSS should be true beforehand, because
that's the way the previous test left it -- the testing framework doesn't clear
these settings in between tests.  (Thus the first test of styleWithCSS on the
page also tests the default value of the state.)  But we set it to false, so
after the tests it should be false.

We expect the indeterm for bold to be false both before and after, because
before nothing is bold, and after everything is bold.  Value should be ""
before and after, because it always is for bold.  The state before should be
false, but after should have changed to true.