2015-12-02 10:49:40 +08:00
|
|
|
class ContenteditableTestHarness {
|
|
|
|
|
2015-12-03 04:43:11 +08:00
|
|
|
constructor(client) {
|
2015-12-02 10:49:40 +08:00
|
|
|
this.client = client;
|
|
|
|
}
|
|
|
|
|
|
|
|
init() {
|
|
|
|
return this.client.execute(() => {
|
|
|
|
ce = document.querySelector(".contenteditable")
|
|
|
|
ce.innerHTML = ""
|
|
|
|
ce.focus()
|
2015-12-03 04:43:11 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
test({keys, expectedHTML, expectedSelectionResolver}) {
|
|
|
|
return this.client.keys(keys).then(()=>{
|
|
|
|
return this.expectHTML(expectedHTML)
|
|
|
|
}).then(()=>{
|
|
|
|
return this.expectSelection(expectedSelectionResolver)
|
2015-12-02 10:49:40 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
expectHTML(expectedHTML) {
|
2015-12-03 04:43:11 +08:00
|
|
|
return this.client.execute(() => {
|
|
|
|
return document.querySelector(".contenteditable").innerHTML
|
|
|
|
}).then(({value})=>{
|
|
|
|
expect(value).toBe(expectedHTML)
|
2015-12-02 10:49:40 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
expectSelection(callback) {
|
2015-12-03 04:43:11 +08:00
|
|
|
// Since `execute` fires parameters to Selenium via REST API, we can
|
|
|
|
// only pass strings. We serialize the callback so we can run it in
|
|
|
|
// the correct execution environment of the window instead of the
|
|
|
|
// Selenium wrapper.
|
|
|
|
return this.client.execute((callbackStr) => {
|
|
|
|
eval(`callback=${callbackStr}`);
|
2015-12-02 10:49:40 +08:00
|
|
|
ce = document.querySelector(".contenteditable")
|
|
|
|
expectSel = callback(ce)
|
|
|
|
|
|
|
|
anchorNode = expectSel.anchorNode || expectSel.node || "No anchorNode found"
|
|
|
|
focusNode = expectSel.focusNode || expectSel.node || "No focusNode found"
|
|
|
|
anchorOffset = expectSel.anchorOffset || expectSel.offset || 0
|
|
|
|
focusOffset = expectSel.focusOffset || expectSel.offset || 0
|
|
|
|
|
2015-12-22 11:58:01 +08:00
|
|
|
nodeData = (node) => {
|
|
|
|
if(node.nodeType === Node.TEXT_NODE) {
|
|
|
|
return node.data
|
|
|
|
} else {
|
|
|
|
return node.outerHTML
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-02 10:49:40 +08:00
|
|
|
selection = document.getSelection()
|
|
|
|
|
2015-12-03 04:43:11 +08:00
|
|
|
return {
|
|
|
|
anchorNodeMatch: selection.anchorNode === anchorNode,
|
|
|
|
focusNodeMatch: selection.focusNode === focusNode,
|
|
|
|
anchorOffsetMatch: selection.anchorOffset === anchorOffset,
|
|
|
|
focusOffsetMatch: selection.focusOffset === focusOffset,
|
2015-12-22 11:58:01 +08:00
|
|
|
expectedAnchorNode: nodeData(anchorNode),
|
|
|
|
expectedFocusNode: nodeData(focusNode),
|
2015-12-03 04:43:11 +08:00
|
|
|
expectedAnchorOffset: anchorOffset,
|
|
|
|
expectedFocusOffset: focusOffset,
|
2015-12-22 11:58:01 +08:00
|
|
|
actualAnchorNode: nodeData(selection.anchorNode),
|
|
|
|
actualFocusNode: nodeData(selection.focusNode),
|
2015-12-03 04:43:11 +08:00
|
|
|
actualAnchorOffset: selection.anchorOffset,
|
|
|
|
actualFocusOffset: selection.focusOffset,
|
|
|
|
}
|
|
|
|
|
|
|
|
}, callback.toString()).then(({value}) => {
|
|
|
|
matchInfo = value
|
|
|
|
|
|
|
|
allMatched = true;
|
|
|
|
if (!matchInfo.anchorNodeMatch) {
|
|
|
|
console.errorColor("\nAnchor nodes don't match")
|
|
|
|
console.errorColor(`Expected: "${matchInfo.actualAnchorNode}" to be "${matchInfo.expectedAnchorNode}"`);
|
|
|
|
allMatched = false;
|
|
|
|
}
|
|
|
|
if (!matchInfo.focusNodeMatch) {
|
|
|
|
console.errorColor("\nFocus nodes don't match")
|
|
|
|
console.errorColor(`Expected: "${matchInfo.actualFocusNode}" to be "${matchInfo.expectedFocusNode}"`);
|
|
|
|
allMatched = false;
|
|
|
|
}
|
|
|
|
if (!matchInfo.anchorOffsetMatch) {
|
|
|
|
console.errorColor("\nAnchor offsets don't match")
|
|
|
|
console.errorColor(`Expected: ${matchInfo.actualAnchorOffset} to be ${matchInfo.expectedAnchorOffset}`);
|
|
|
|
allMatched = false;
|
|
|
|
}
|
|
|
|
if (!matchInfo.focusOffsetMatch) {
|
|
|
|
console.errorColor("\nFocus offsets don't match")
|
|
|
|
console.errorColor(`Expected: ${matchInfo.actualFocusOffset} to be ${matchInfo.expectedFocusOffset}`);
|
|
|
|
allMatched = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
outMsgDescription = "matched. See discrepancies above"
|
|
|
|
if (allMatched) { outMsg = outMsgDescription
|
|
|
|
} else { outMsg = "Selection" }
|
|
|
|
// "Expected Selection to be matched. See discrepancies above"
|
|
|
|
expect(outMsg).toBe(outMsgDescription);
|
2015-12-02 10:49:40 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = ContenteditableTestHarness
|