I'm trying to create a browser extension in Dart. Currently, I'm using the webext
package, which basically emulates the typical JS environment in Dart.
In the main()
function of content.dart
file, I wish to manipulate the DOM. The document
variable is available and is of type HtmlDocument
, which comes from dart:html
. This is all well and good, but how would you create a testing harness with that, considering HtmlDocument
doesn't have a public constructor?
I've tried to use the parent of HtmlDocument
, i.e., Document
. Something like this for a custom HTML tag:
import 'dart:html';
void main() {
final Document document = Document();
document.registerElement(CustomElement.tag, CustomElement);
document.createElement(CustomElement.tag);
}
class CustomElement extends HtmlElement {
static const String tag = 'custom-tag';
factory CustomElement.created() => null;
}
But the Document
class doesn't have the necessary API and registering custom tags is not supported apparently — the supportsRegisterElement
getter gives me back false
, which might be related to Chrome or Dartium, I'm not sure.
I still don't know why creating a custom HtmlElement
isn't working in this case, but there's a good enough way around the overall problem: DomParser
.
You can use the parseFromString
method to parse an HTML string into a Document
and use it as a simplified way to test your code. The DomParser
's behavior emulates the its JS counterpart: DOMParser
.
An example:
import 'dart:html' show Document, DomParser, Element;
import 'package:test/test.dart' show expect, test;
void main() {
const String htmlAsString = '<p>A paragraph</p>';
final Document document = DomParser().parseFromString(htmlAsString, 'text/html');
test('Checking the text inside the paragraph', () {
final Element paragraph = document.querySelector('p');
expect(paragraph.text, 'A paragraph');
});
}
Note that using dart:io
to open the HTML fixtures/fakes/mocks won't be possible because most of its functionalities aren't supported by the browser.
Custom tags can also be used in the stringed HTML above, they won't have custom classes, they will all be of runtime type HtmlElement
, which is a subclass of Element
. The parser will be able to handle them by changing/initializing their tagName
s in the background — it actually basically seems to do this for all tags.