diff --git a/src/tests/frontend/specs/importexport.js b/src/tests/frontend/specs/importexport.js
index 4eb95eeb0..73798eca9 100644
--- a/src/tests/frontend/specs/importexport.js
+++ b/src/tests/frontend/specs/importexport.js
@@ -1,329 +1,604 @@
'use strict';
-describe('import functionality', function () {
- beforeEach(function (cb) {
- helper.newPad(cb); // creates a new pad
- this.timeout(60000);
- });
-
- function getinnertext() {
- const inner = helper.padInner$;
- if (!inner) {
- return '';
- }
- let newtext = '';
- inner('div').each((line, el) => {
- newtext += `${el.innerHTML}\n`;
- });
- return newtext;
- }
- function importrequest(data, importurl, type) {
- let error;
- const result = $.ajax({
- url: importurl,
- type: 'post',
- processData: false,
- async: false,
- contentType: 'multipart/form-data; boundary=boundary',
- accepts: {
- text: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
- },
- data: [
- 'Content-Type: multipart/form-data; boundary=--boundary',
- '',
- '--boundary',
- `Content-Disposition: form-data; name="file"; filename="import.${type}"`,
- 'Content-Type: text/plain',
- '',
- data,
- '',
- '--boundary',
- ].join('\r\n'),
- error(res) {
- error = res;
- },
- });
- expect(error).to.be(undefined);
- return result;
- }
- function exportfunc(link) {
- const exportresults = [];
- $.ajaxSetup({
- async: false,
- });
- $.get(`${link}/export/html`, (data) => {
- const start = data.indexOf('
');
- const end = data.indexOf('');
- const html = data.substr(start + 6, end - start - 6);
- exportresults.push(['html', html]);
- });
- $.get(`${link}/export/txt`, (data) => {
- exportresults.push(['txt', data]);
- });
- return exportresults;
- }
-
- xit('import a pad with newlines from txt', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const textWithNewLines = 'imported text\nnewline';
- importrequest(textWithNewLines, importurl, 'txt');
- helper.waitFor(() => expect(getinnertext())
- .to.be('imported text \nnewline \n \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be('imported text newline ');
- expect(results[1][1]).to.be('imported text\nnewline\n\n');
- done();
- });
- xit('import a pad with newlines from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithNewLines = 'htmltext newline';
- importrequest(htmlWithNewLines, importurl, 'html');
- helper.waitFor(() => expect(getinnertext())
- .to.be('htmltext \nnewline \n \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be('htmltext newline ');
- expect(results[1][1]).to.be('htmltext\nnewline\n\n');
- done();
- });
- xit('import a pad with attributes from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithNewLines = 'htmltext' +
- 'newline ';
- importrequest(htmlWithNewLines, importurl, 'html');
- helper.waitFor(() => expect(getinnertext())
- .to.be('htmltext \n' +
- 'newline \n \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1])
- .to.be('htmltextnewline ');
- expect(results[1][1]).to.be('htmltext\nnewline\n\n');
- done();
- });
- xit('import a pad with bullets from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = 'bullet line 1 ' +
- 'bullet line 2 bullet2 line 1 ' +
- 'bullet2 line 2 ';
- importrequest(htmlWithBullets, importurl, 'html');
- helper.waitFor(() => expect(getinnertext()).to.be(
- '\n' +
- '\n' +
- '\n' +
- '\n' +
- ' \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- 'bullet line 1 bullet line 2 ' +
- 'bullet2 line 1 bullet2 line 2 ');
- expect(results[1][1])
- .to.be('\t* bullet line 1\n\t* bullet line 2\n' +
- '\t\t* bullet2 line 1\n\t\t* bullet2 line 2\n\n');
- done();
- });
- xit('import a pad with bullets and newlines from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = ' ';
- importrequest(htmlWithBullets, importurl, 'html');
- helper.waitFor(() => expect(getinnertext()).to.be(
- '\n' +
- ' \n' +
- '\n' +
- '\n' +
- ' \n' +
- '\n' +
- ' \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- '' +
- 'bullet line 2 ' +
- ' ');
- expect(results[1][1]).to.be(
- '\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t* bullet2 line 2\n\n');
- done();
- });
- xit('import a pad with bullets and newlines and attributes from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = ' ' +
- '' +
- '' +
- 'bullet4 line 2 bisu ' +
- 'bullet4 line 2 bs ' +
- 'bullet4 line 2 u ' +
- 'uis ';
- importrequest(htmlWithBullets, importurl, 'html');
- helper.waitFor(() => expect(getinnertext()).to.be(
- '\n \n' +
- '\n' +
- '\n \n' +
- '' +
- 'bullet4 line 2 bisu \n' +
- '\n' +
- 'bullet4 line 2 u ' +
- 'uis \n' +
- ' \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- '' +
- 'bullet4 line 2 bisu' +
- ' bullet4 line 2 bs ' +
- 'bullet4 line 2 uuis ');
- expect(results[1][1]).to.be(
- '\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t\t\t* bullet4 line 2' +
- ' bisu\n\t\t\t\t* bullet4 line 2 bs\n\t\t\t\t* bullet4 line 2 uuis\n\n');
- done();
- });
- xit('import a pad with nested bullets from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = '' +
- 'bullet4 line 2 ' +
- 'bullet4 line 2 bullet4 line 2 bullet3 line 1 ' +
- ' bullet2 line 1 ';
- importrequest(htmlWithBullets, importurl, 'html');
- const oldtext = getinnertext();
- helper.waitFor(() => oldtext !== getinnertext()
- // return expect(getinnertext()).to.be('\
- // \n\
- // \n\
- // \n\
- // \n\
- // \n\
- // \n\
- // \n')
- );
-
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- 'bullet line 1 bullet line 2 ' +
- 'bullet2 line 1 bullet4 line 2 ' +
- 'bullet4 line 2 bullet4 line 2 bullet3 line 1 ' +
- 'bullet2 line 1 ');
- expect(results[1][1]).to.be(
- '\t* bullet line 1\n\t* bullet line 2\n\t\t* bullet2 line 1\n\t\t\t\t* bullet4 line 2' +
- '\n\t\t\t\t* bullet4 line 2\n\t\t\t\t* bullet4 line 2\n\t\t\t* bullet3 line 1' +
- '\n\t* bullet2 line 1\n\n');
- done();
- });
- xit('import with 8 levels of bullets and newlines and attributes from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets =
- '' +
- '' +
- 'bullet4 line 2 bisu ' +
- 'bullet4 line 2 bs bullet4 line 2 u' +
- ' uis ' +
- ' ';
- importrequest(htmlWithBullets, importurl, 'html');
- helper.waitFor(() => expect(getinnertext()).to.be(
- '\n \n' +
- '\n' +
- '\n \n' +
- 'bullet4 line 2 bisu ' +
- ' \n' +
- '\n' +
+describe('importexport.js', function () {
+ const testCases = [
+ {
+ name: 'text with newlines',
+ inputText: [
+ 'imported text\n',
+ 'newline',
+ ].join(''),
+ wantPadLines: [
+ 'imported text ',
+ 'newline ',
+ ],
+ wantExportHtmlBody: [
+ 'imported text ',
+ 'newline ',
+ ].join(''),
+ wantExportText: [
+ 'imported text\n',
+ 'newline\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with newlines',
+ inputHtmlBody: [
+ 'htmltext ',
+ 'newline',
+ ].join(''),
+ wantPadLines: [
+ 'htmltext ',
+ 'newline ',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ 'htmltext ',
+ 'newline ',
+ ' ',
+ ].join(''),
+ wantExportText: [
+ 'htmltext\n',
+ 'newline\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with attributes',
+ inputHtmlBody: [
+ 'htmltext ',
+ 'newline ',
+ ].join(''),
+ wantPadLines: [
+ 'htmltext ',
+ 'newline ',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ 'htmltext ',
+ 'newline ',
+ ' ',
+ ].join(''),
+ wantExportText: [
+ 'htmltext\n',
+ 'newline\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with bullets',
+ inputHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' bullet2 line 2 ',
+ ' ',
+ ' ',
+ ' ',
+ ].join(''),
+ wantPadLines: [
+ '',
+ '',
+ '',
+ '',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' bullet2 line 2 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t* bullet line 1\n',
+ '\t* bullet line 2\n',
+ '\t\t* bullet2 line 1\n',
+ '\t\t* bullet2 line 2\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with bullets and newlines',
+ inputHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' ',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' bullet2 line 2 ',
+ ' ',
+ ' ',
+ ' ',
+ ].join(''),
+ wantPadLines: [
+ '',
+ ' ',
+ '',
+ '',
+ ' ',
+ '',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' ',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' bullet2 line 2 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t* bullet line 1\n',
+ '\n',
+ '\t* bullet line 2\n',
+ '\t\t* bullet2 line 1\n',
+ '\n',
+ '\t\t* bullet2 line 2\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with bullets, newlines, and attributes',
+ inputHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' ',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 bisu ' +
+ ' ',
+ ' bullet4 line 2 bs ',
+ ' bullet4 line 2 u ' +
+ 'uis ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].join(''),
+ wantPadLines: [
+ '',
+ ' ',
+ '',
+ '',
+ ' ',
+ '' +
+ 'bullet4 line 2 bisu ',
+ '',
'bullet4 line 2 u ' +
- 'uis ' +
- ' \n' +
- '\n' +
- '\n' +
- '\n' +
- ' \n'));
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- ' ' +
- '' +
- 'bullet4 line 2 bisu ' +
- 'bullet4 line 2 bs bullet4 line 2 u' +
- 'uis ');
- expect(results[1][1]).to.be(
- '\t* bullet line 1\n\n\t* bullet line 2\n\t\t* ' +
- 'bullet2 line 1\n\n\t\t\t\t* bullet4 line 2 bisu\n\t\t\t\t* bullet4 line 2 ' +
- 'bs\n\t\t\t\t* bullet4 line 2 uuis\n\t\t\t\t\t\t\t\t* foo\n\t\t\t\t\t\t\t\t* ' +
- 'foobar bs\n\t\t\t\t\t* foobar\n\n');
- done();
+ 'uis ',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 bisu ',
+ ' bullet4 line 2 bs ',
+ ' bullet4 line 2 uuis ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t* bullet line 1\n',
+ '\n',
+ '\t* bullet line 2\n',
+ '\t\t* bullet2 line 1\n',
+ '\n',
+ '\t\t\t\t* bullet4 line 2 bisu\n',
+ '\t\t\t\t* bullet4 line 2 bs\n',
+ '\t\t\t\t* bullet4 line 2 uuis\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with nested bullets',
+ inputHtmlBody: [
+ '',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 ',
+ ' bullet4 line 2 ',
+ ' bullet4 line 2 ',
+ ' ',
+ ' ',
+ ' bullet3 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].join(''),
+ wantPadLines: [
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 ',
+ ' bullet4 line 2 ',
+ ' bullet4 line 2 ',
+ ' ',
+ ' ',
+ ' bullet3 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t* bullet line 1\n',
+ '\t* bullet line 2\n',
+ '\t\t* bullet2 line 1\n',
+ '\t\t\t\t* bullet4 line 2\n',
+ '\t\t\t\t* bullet4 line 2\n',
+ '\t\t\t\t* bullet4 line 2\n',
+ '\t\t\t* bullet3 line 1\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with 8 levels of bullets, newlines, and attributes',
+ inputHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' ',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 bisu' +
+ ' ',
+ ' bullet4 line 2 bs ',
+ ' bullet4 line 2 u ' +
+ 'uis ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' foo ',
+ ' foobar bs ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].join(''),
+ wantPadLines: [
+ '',
+ ' ',
+ '',
+ '',
+ ' ',
+ '' +
+ 'bullet4 line 2 bisu ',
+ '',
+ 'bullet4 line 2 u ' +
+ 'uis ',
+ '',
+ '',
+ '',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' bullet line 1 ',
+ ' ',
+ ' ',
+ '',
+ ' bullet line 2',
+ ' ',
+ ' bullet2 line 1 ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ '',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' bullet4 line 2 bisu ',
+ ' bullet4 line 2 bs ',
+ ' bullet4 line 2 uuis ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' foo ',
+ ' foobar bs ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' foobar ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t* bullet line 1\n',
+ '\n',
+ '\t* bullet line 2\n',
+ '\t\t* bullet2 line 1\n',
+ '\n',
+ '\t\t\t\t* bullet4 line 2 bisu\n',
+ '\t\t\t\t* bullet4 line 2 bs\n',
+ '\t\t\t\t* bullet4 line 2 uuis\n',
+ '\t\t\t\t\t\t\t\t* foo\n',
+ '\t\t\t\t\t\t\t\t* foobar bs\n',
+ '\t\t\t\t\t* foobar\n',
+ '\n',
+ ].join(''),
+ },
+ {
+ name: 'HTML with ordered lists',
+ inputHtmlBody: [
+ 'number 1 line 1 ',
+ 'number 2 line 2 ',
+ ].join(''),
+ wantPadLines: [
+ 'number 1 line 1 ',
+ 'number 2 line 2 ',
+ ' ',
+ ],
+ wantExportHtmlBody: [
+ '',
+ ' number 1 line 1 ',
+ ' number 2 line 2 ',
+ ' ',
+ ' ',
+ ].map((l) => l.replace(/^\s+/, '')).join(''),
+ wantExportText: [
+ '\t1. number 1 line 1\n',
+ '\t2. number 2 line 2\n',
+ '\n',
+ ].join(''),
+ },
+ ];
+
+ let confirm;
+ before(async function () {
+ this.timeout(60000);
+ await new Promise(
+ (resolve, reject) => helper.newPad((err) => err != null ? reject(err) : resolve()));
+ confirm = helper.padChrome$.window.confirm;
+ helper.padChrome$.window.confirm = () => true;
+ // As of 2021-02-22 a mutable FileList cannot be directly created so DataTransfer is used as a
+ // hack to access a mutable FileList for testing the ' ' element. DataTransfer
+ // itself is quite new so support for it is tested here. See:
+ // * https://github.com/whatwg/html/issues/3269
+ // * https://stackoverflow.com/q/47119426
+ try {
+ const dt = new DataTransfer();
+ dt.items.add(new File(['testing'], 'file.txt', {type: 'text/plain'}));
+ // Supposedly all modern browsers support a settable HTMLInputElement.files property, but
+ // Firefox 52 complains.
+ helper.padChrome$('#importform input[type=file]')[0].files = dt.files;
+ } catch (err) {
+ return this.skip();
+ }
});
- xit('import a pad with ordered lists from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = '' +
- 'number 1 line 1 ' +
- 'number 2 line 2 ';
- importrequest(htmlWithBullets, importurl, 'html');
- console.error(getinnertext());
- expect(getinnertext()).to.be(
- 'number 1 line 1 \n' +
- 'number 2 line 2 \n' +
- ' \n');
- const results = exportfunc(helper.padChrome$.window.location.href);
- expect(results[0][1]).to.be(
- 'number 1 line 1 ' +
- 'number 2 line 2 ');
- expect(results[1][1]).to.be('');
- done();
+ after(async function () {
+ helper.padChrome$.window.confirm = confirm;
});
- xit('import a pad with ordered lists and newlines from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = '' +
- 'number 9 line 1 ' +
- 'number 10 line 2 ' +
- 'number 2 times line 1 ' +
- 'number 2 times line 2 ';
- importrequest(htmlWithBullets, importurl, 'html');
- expect(getinnertext()).to.be(
- 'number 9 line 1 \n' +
- ' \n' +
- 'number 10 line 2 ' +
- ' \n' +
- 'number 2 times line 1 \n' +
- ' \n' +
- 'number 2 times line 2 \n' +
- ' \n');
- const results = exportfunc(helper.padChrome$.window.location.href);
- console.error(results);
- done();
- });
- xit('import with nested ordered lists and attributes and newlines from html', function (done) {
- const importurl = `${helper.padChrome$.window.location.href}/import`;
- const htmlWithBullets = '' +
- 'bold strikethrough italics underline ' +
- ' line 1bold ' +
- '' +
- 'number 10 line 2 ' +
- 'number 2 times line 1 ' +
- '' +
- 'number 2 times line 2 ';
- importrequest(htmlWithBullets, importurl, 'html');
- expect(getinnertext()).to.be(
- '' +
- 'bold strikethrough italics underline ' +
- ' line 1bold \n' +
- ' \n' +
- 'number 10 line 2 \n' +
- '' +
- 'number 2 times line 1 \n' +
- ' \n' +
- 'number 2 times line 2 \n' +
- ' \n');
- const results = exportfunc(helper.padChrome$.window.location.href);
- console.error(results);
- done();
+
+ beforeEach(async function () {
+ const popup = helper.padChrome$('#import_export');
+ const isVisible = () => popup.hasClass('popup-show');
+ if (isVisible()) return;
+ const button = helper.padChrome$('button[data-l10n-id="pad.toolbar.import_export.title"]');
+ button.click();
+ await helper.waitForPromise(isVisible);
});
+
+ const docToHtml = (() => {
+ const s = new XMLSerializer();
+ return (doc) => s.serializeToString(doc);
+ })();
+
+ const htmlToDoc = (() => {
+ const p = new DOMParser();
+ return (html) => p.parseFromString(html, 'text/html');
+ })();
+
+ const htmlBodyToDoc = (htmlBody) => {
+ const doc = document.implementation.createHTMLDocument();
+ $('body', doc).html(htmlBody);
+ return doc;
+ };
+
+ for (const tc of testCases) {
+ describe(tc.name, function () {
+ it('import', async function () {
+ const ext = tc.inputHtmlBody ? 'html' : 'txt';
+ const contents = ext === 'html' ? docToHtml(htmlBodyToDoc(tc.inputHtmlBody)) : tc.inputText;
+ // DataTransfer is used as a hacky way to get a mutable FileList. For details, see:
+ // https://stackoverflow.com/q/47119426
+ const dt = new DataTransfer();
+ dt.items.add(new File([contents], `file.${ext}`, {type: 'text/plain'}));
+ const form = helper.padChrome$('#importform');
+ form.find('input[type=file]')[0].files = dt.files;
+ form.find('#importsubmitinput').submit();
+ try {
+ await helper.waitForPromise(() => {
+ const got = helper.linesDiv();
+ if (got.length !== tc.wantPadLines.length) return false;
+ for (let i = 0; i < got.length; i++) {
+ const gotDiv = $('').html(got[i].html());
+ const wantDiv = $('
').html(tc.wantPadLines[i]);
+ if (!gotDiv[0].isEqualNode(wantDiv[0])) return false;
+ }
+ return true;
+ });
+ } catch (err) {
+ const formatLine = (l) => ` ${JSON.stringify(l)}`;
+ const g = helper.linesDiv().map((div) => formatLine(div.html())).join('\n');
+ const w = tc.wantPadLines.map(formatLine).join('\n');
+ throw new Error(`Import failed. Got pad lines:\n${g}\nWant pad lines:\n${w}`);
+ }
+ });
+
+ it('export to HTML', async function () {
+ const link = helper.padChrome$('#exporthtmla').attr('href');
+ const url = new URL(link, helper.padChrome$.window.location.href).href;
+ const gotHtml = await $.ajax({url, dataType: 'html'});
+ const gotBody = $('body', htmlToDoc(gotHtml));
+ gotBody.html(gotBody.html().replace(/^\s+|\s+$/g, ''));
+ const wantBody = $('body', htmlBodyToDoc(tc.wantExportHtmlBody));
+ if (!gotBody[0].isEqualNode(wantBody[0])) {
+ throw new Error(`Got exported HTML body:\n ${JSON.stringify(gotBody.html())}\n` +
+ `Want HTML body:\n ${JSON.stringify(wantBody.html())}`);
+ }
+ });
+
+ it('export to text', async function () {
+ const link = helper.padChrome$('#exportplaina').attr('href');
+ const url = new URL(link, helper.padChrome$.window.location.href).href;
+ const got = await $.ajax({url, dataType: 'text'});
+ expect(got).to.be(tc.wantExportText);
+ });
+ });
+ }
});