popup-options.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. var t = require('assert')
  2. var defaults = require('./utils/defaults')
  3. module.exports = ({popup, advanced, content}) => {
  4. before(async () => {
  5. await defaults({popup, advanced, content})
  6. })
  7. describe('button - raw/markdown', () => {
  8. before(async () => {
  9. // popup
  10. await popup.bringToFront()
  11. // defaults button
  12. await popup.click('button:nth-of-type(2)')
  13. })
  14. it('render markdown as html', async () => {
  15. // go to page serving markdown as text/markdown
  16. await content.goto('http://localhost:3000/correct-content-type')
  17. await content.bringToFront()
  18. await content.waitForTimeout(300)
  19. t.equal(
  20. await content.evaluate(() =>
  21. document.querySelector('#_html p strong').innerText
  22. ),
  23. 'bold',
  24. 'markdown should be rendered'
  25. )
  26. // popup
  27. await popup.bringToFront()
  28. t.strictEqual(
  29. await popup.evaluate(() =>
  30. state.raw
  31. ),
  32. false,
  33. 'state.raw should equal false'
  34. )
  35. t.equal(
  36. await popup.evaluate(() =>
  37. document.querySelector('.m-button:first-child').innerText.toLowerCase()
  38. ),
  39. 'markdown',
  40. 'button text should equal markdown'
  41. )
  42. })
  43. it('display raw markdown', async () => {
  44. // raw button
  45. await popup.bringToFront()
  46. await popup.click('button:nth-of-type(1)')
  47. // content auto reloads, but there is no way to have both tabs active
  48. await content.bringToFront()
  49. await content.reload()
  50. t.equal(
  51. await content.evaluate(() =>
  52. document.querySelector('#_markdown').innerText
  53. ),
  54. '**bold**',
  55. 'markdown should not be rendered'
  56. )
  57. // popup
  58. await popup.bringToFront()
  59. t.strictEqual(
  60. await popup.evaluate(() =>
  61. state.raw
  62. ),
  63. true,
  64. 'state.raw should equal true'
  65. )
  66. t.equal(
  67. await popup.evaluate(() =>
  68. document.querySelector('.m-button:first-child').innerText.toLowerCase()
  69. ),
  70. 'html',
  71. 'button text should equal html'
  72. )
  73. })
  74. })
  75. describe('set theme', () => {
  76. before(async () => {
  77. // popup
  78. await popup.bringToFront()
  79. // defaults button
  80. await popup.click('button:nth-of-type(2)')
  81. // theme tab
  82. await popup.click('.m-tabs a:nth-of-type(1)')
  83. })
  84. it('github theme should be set by default', async () => {
  85. // go to page serving markdown as text/markdown
  86. await content.goto('http://localhost:3000/correct-content-type')
  87. await content.bringToFront()
  88. await content.waitForTimeout(300)
  89. t.strictEqual(
  90. await content.evaluate(() =>
  91. /github\.css$/.test(
  92. document.querySelector('#_theme').getAttribute('href')
  93. )
  94. ),
  95. true,
  96. 'github theme styles should be included'
  97. )
  98. })
  99. it('set github-dark theme', async () => {
  100. // select github-dark theme
  101. await popup.bringToFront()
  102. await popup.select('.m-panel:nth-of-type(1) select', 'github-dark')
  103. // content auto reloads, but there is no way to have both tabs active
  104. await content.bringToFront()
  105. await content.reload()
  106. t.strictEqual(
  107. await content.evaluate(() =>
  108. /github-dark\.css$/.test(
  109. document.querySelector('#_theme').getAttribute('href')
  110. )
  111. ),
  112. true,
  113. 'github-dark theme styles should be included'
  114. )
  115. })
  116. it('popup should preserve state', async () => {
  117. // reload popup
  118. await popup.bringToFront()
  119. await popup.reload()
  120. await popup.waitForTimeout(300)
  121. t.equal(
  122. await popup.evaluate(() =>
  123. state.theme
  124. ),
  125. 'github-dark',
  126. 'state.theme should equal github-dark'
  127. )
  128. t.equal(
  129. await popup.evaluate(() =>
  130. document.querySelectorAll('.m-panel:nth-of-type(1) select option')[
  131. document.querySelector('.m-panel:nth-of-type(1) select').selectedIndex
  132. ].innerText
  133. ),
  134. 'github-dark',
  135. 'dom select option should be github-dark'
  136. )
  137. })
  138. })
  139. describe('set compiler options - marked', () => {
  140. before(async () => {
  141. // popup
  142. await popup.bringToFront()
  143. // defaults button
  144. await popup.click('button:nth-of-type(2)')
  145. // compiler tab
  146. await popup.click('.m-tabs a:nth-of-type(2)')
  147. })
  148. it('gfm is enabled by default', async () => {
  149. // go to page serving markdown as text/markdown
  150. await content.goto('http://localhost:3000/compiler-options-marked')
  151. await content.bringToFront()
  152. await content.waitForTimeout(300)
  153. t.equal(
  154. await content.evaluate(() =>
  155. document.querySelector('#_html p del').innerText
  156. ),
  157. 'strikethrough',
  158. 'gfm should be rendered'
  159. )
  160. })
  161. it('gfm is disabled', async () => {
  162. // disable gfm
  163. await popup.bringToFront()
  164. // gfm switch
  165. await popup.click('.m-panel:nth-of-type(2) .m-switch:nth-of-type(2)')
  166. // content auto reloads, but there is no way to have both tabs active
  167. await content.bringToFront()
  168. await content.reload()
  169. await content.waitForTimeout(300)
  170. t.equal(
  171. await content.evaluate(() =>
  172. document.querySelector('#_html p').innerText
  173. ),
  174. '~~strikethrough~~',
  175. 'gfm should not be rendered'
  176. )
  177. })
  178. it('popup should preserve state', async () => {
  179. // reload popup
  180. await popup.bringToFront()
  181. await popup.reload()
  182. await popup.waitForTimeout(300)
  183. t.equal(
  184. await popup.evaluate(() =>
  185. document.querySelectorAll('.m-panel:nth-of-type(2) .m-select option')[
  186. document.querySelector('.m-panel:nth-of-type(2) .m-select').selectedIndex
  187. ].innerText
  188. ),
  189. 'marked',
  190. 'dom select option should be marked'
  191. )
  192. t.strictEqual(
  193. await popup.evaluate(() =>
  194. state.options.gfm
  195. ),
  196. false,
  197. 'state.options.gfm should be false'
  198. )
  199. t.strictEqual(
  200. await popup.evaluate(() =>
  201. document.querySelector('.m-panel:nth-of-type(2) .m-switch:nth-of-type(2)').classList.contains('is-checked')
  202. ),
  203. false,
  204. 'dom gfm checkbox should be disabled'
  205. )
  206. })
  207. })
  208. describe('set compiler options - remark', () => {
  209. before(async () => {
  210. // popup
  211. await popup.bringToFront()
  212. // defaults button
  213. await popup.click('button:nth-of-type(2)')
  214. // compiler tab
  215. await popup.click('.m-tabs a:nth-of-type(2)')
  216. })
  217. it('marked should render gfm task lists by default', async () => {
  218. // go to page serving markdown as text/markdown
  219. await content.goto('http://localhost:3000/compiler-options-remark')
  220. await content.bringToFront()
  221. await content.waitForTimeout(300)
  222. t.equal(
  223. await content.evaluate(() =>
  224. document.querySelector('#_html ul li').getAttribute('class')
  225. ),
  226. null,
  227. 'no class on dom li'
  228. )
  229. t.strictEqual(
  230. await content.evaluate(() =>
  231. document.querySelector('#_html ul li [type=checkbox]').hasAttribute('disabled')
  232. ),
  233. true,
  234. 'dom li should contain checkbox in it'
  235. )
  236. t.equal(
  237. await content.evaluate(() =>
  238. document.querySelector('#_html ul li').innerText
  239. ),
  240. ' task',
  241. 'dom li should contain the task text'
  242. )
  243. })
  244. it('remark should render gfm task lists by default', async () => {
  245. // select remark compiler
  246. await popup.bringToFront()
  247. await popup.select('.m-panel:nth-of-type(2) select', 'remark')
  248. // content auto reloads, but there is no way to have both tabs active
  249. await content.bringToFront()
  250. await content.reload()
  251. await content.waitForTimeout(300)
  252. t.equal(
  253. await content.evaluate(() =>
  254. document.querySelector('#_html ul li').getAttribute('class')
  255. ),
  256. 'task-list-item',
  257. 'dom li should have a class set'
  258. )
  259. t.strictEqual(
  260. await content.evaluate(() =>
  261. document.querySelector('#_html ul li [type=checkbox]').hasAttribute('disabled')
  262. ),
  263. true,
  264. 'dom li should contain checkbox in it'
  265. )
  266. t.equal(
  267. await content.evaluate(() =>
  268. document.querySelector('#_html ul li').innerText
  269. ),
  270. ' task',
  271. 'dom li should contain the task text'
  272. )
  273. })
  274. it('remark disable gfm', async () => {
  275. // redraw popup
  276. await popup.bringToFront()
  277. await popup.reload()
  278. await popup.waitForTimeout(300)
  279. // disable gfm - gfm switch
  280. await popup.click('.m-panel:nth-of-type(2) .m-switch[title~=GFM]')
  281. // content auto reloads, but there is no way to have both tabs active
  282. await content.bringToFront()
  283. await content.reload()
  284. await content.waitForTimeout(300)
  285. t.equal(
  286. await content.evaluate(() =>
  287. document.querySelector('#_html ul li').innerText
  288. ),
  289. '[ ] task',
  290. 'gfm task lists should not be rendered'
  291. )
  292. })
  293. it('popup should preserve state', async () => {
  294. // reload popup
  295. await popup.bringToFront()
  296. await popup.reload()
  297. await popup.waitForTimeout(300)
  298. t.equal(
  299. await popup.evaluate(() =>
  300. document.querySelectorAll('.m-panel:nth-of-type(2) .m-select option')[
  301. document.querySelector('.m-panel:nth-of-type(2) .m-select').selectedIndex
  302. ].innerText
  303. ),
  304. 'remark',
  305. 'dom select option should be remark'
  306. )
  307. t.strictEqual(
  308. await popup.evaluate(() =>
  309. state.options.gfm
  310. ),
  311. false,
  312. 'state.options.gfm should be false'
  313. )
  314. t.strictEqual(
  315. await popup.evaluate(() =>
  316. document.querySelector('.m-panel:nth-of-type(2) .m-switch[title~=GFM]').classList.contains('is-checked')
  317. ),
  318. false,
  319. 'dom gfm checkbox should be disabled'
  320. )
  321. })
  322. })
  323. describe('set content options - toc', () => {
  324. before(async () => {
  325. // popup
  326. await popup.bringToFront()
  327. // defaults button
  328. await popup.click('button:nth-of-type(2)')
  329. // content tab
  330. await popup.click('.m-tabs a:nth-of-type(3)')
  331. })
  332. it('toc is disabled by default', async () => {
  333. // go to page serving markdown as text/markdown
  334. await content.goto('http://localhost:3000/content-options-toc')
  335. await content.bringToFront()
  336. await content.waitForTimeout(300)
  337. t.strictEqual(
  338. await content.evaluate(() =>
  339. document.querySelector('#_toc')
  340. ),
  341. null,
  342. 'toc should be disabled'
  343. )
  344. })
  345. it('enable toc', async () => {
  346. // enable toc
  347. await popup.bringToFront()
  348. // toc switch
  349. await popup.click('.m-panel:nth-of-type(3) .m-switch:nth-of-type(3)')
  350. // content auto reloads, but there is no way to have both tabs active
  351. await content.bringToFront()
  352. await content.reload()
  353. await content.waitForTimeout(300)
  354. t.deepStrictEqual(
  355. await content.evaluate(() =>
  356. Array.from(document.querySelectorAll('#_toc ._ul a'))
  357. .map((a) => ({href: a.getAttribute('href'), text: a.innerText}))
  358. ),
  359. [
  360. {href: '#h1', text: 'h1'},
  361. {href: '#h2', text: 'h2'},
  362. {href: '#h3', text: 'h3'},
  363. ],
  364. 'toc should be rendered'
  365. )
  366. })
  367. })
  368. describe('set content options - scroll', () => {
  369. before(async () => {
  370. // popup
  371. await popup.bringToFront()
  372. // defaults button
  373. await popup.click('button:nth-of-type(2)')
  374. // content tab
  375. await popup.click('.m-tabs a:nth-of-type(3)')
  376. })
  377. it('preserve scroll position by default', async () => {
  378. // go to page serving markdown as text/markdown
  379. await content.goto('http://localhost:3000/content-options-scroll')
  380. await content.bringToFront()
  381. await content.waitForTimeout(300)
  382. // scroll down 200px
  383. await content.evaluate(() =>
  384. document.querySelector('html').scrollTop = 200
  385. )
  386. await content.waitForTimeout(300)
  387. // reload page
  388. await content.reload()
  389. await content.waitForTimeout(300)
  390. t.strictEqual(
  391. await content.evaluate(() =>
  392. document.querySelector('html').scrollTop,
  393. ),
  394. 200,
  395. 'scrollTop should be 200px'
  396. )
  397. })
  398. it('scroll to top', async () => {
  399. // disable scroll option
  400. await popup.bringToFront()
  401. // scroll switch
  402. await popup.click('.m-panel:nth-of-type(3) .m-switch:nth-of-type(2)')
  403. // content auto reloads, but there is no way to have both tabs active
  404. await content.bringToFront()
  405. await content.reload()
  406. await content.waitForTimeout(300)
  407. t.strictEqual(
  408. await content.evaluate(() =>
  409. document.querySelector('html').scrollTop,
  410. ),
  411. 0,
  412. 'scrollTop should be 0px'
  413. )
  414. // scroll down 200px
  415. await content.evaluate(() =>
  416. document.querySelector('html').scrollTop = 200
  417. )
  418. await content.waitForTimeout(300)
  419. // reload page
  420. await content.reload()
  421. await content.waitForTimeout(300)
  422. t.strictEqual(
  423. await content.evaluate(() =>
  424. document.querySelector('html').scrollTop,
  425. ),
  426. 0,
  427. 'scrollTop should be 0px'
  428. )
  429. })
  430. it('scroll to anchor', async () => {
  431. // click on header link
  432. await content.click('h2 a')
  433. await content.waitForTimeout(300)
  434. t.strictEqual(
  435. await content.evaluate(() =>
  436. document.querySelector('html').scrollTop + 1
  437. ),
  438. await content.evaluate(() =>
  439. document.querySelector('h2').offsetTop
  440. ),
  441. 'page should be scrolled to the anchor'
  442. )
  443. // scroll down 200px
  444. await content.evaluate(() =>
  445. document.querySelector('html').scrollTop += 200
  446. )
  447. await content.waitForTimeout(300)
  448. t.strictEqual(
  449. await content.evaluate(() =>
  450. document.querySelector('html').scrollTop + 1
  451. ),
  452. await content.evaluate(() =>
  453. document.querySelector('h2').offsetTop + 200
  454. ),
  455. 'page should be scrolled below the anchor'
  456. )
  457. // reload page
  458. await content.reload()
  459. await content.waitForTimeout(300)
  460. t.strictEqual(
  461. await content.evaluate(() =>
  462. document.querySelector('html').scrollTop
  463. ),
  464. await content.evaluate(() =>
  465. document.querySelector('h2').offsetTop
  466. ),
  467. 'page should be scrolled back to the anchor'
  468. )
  469. })
  470. })
  471. describe('set content options - autoreload', () => {
  472. before(async () => {
  473. // popup
  474. await popup.bringToFront()
  475. // defaults button
  476. await popup.click('button:nth-of-type(2)')
  477. // content tab
  478. await popup.click('.m-tabs a:nth-of-type(3)')
  479. await content.goto('about:blank')
  480. await content.bringToFront()
  481. await content.waitForTimeout(300)
  482. // go to test page
  483. await content.goto('http://localhost:3000/popup-autoreload')
  484. await content.bringToFront()
  485. await content.waitForTimeout(300)
  486. // enable autoreload
  487. await popup.bringToFront()
  488. // autoreload switch
  489. await popup.click('.m-panel:nth-of-type(3) .m-switch:nth-of-type(5)')
  490. // content auto reloads, but there is no way to have both tabs active
  491. await content.bringToFront()
  492. await content.reload()
  493. await content.waitForTimeout(300)
  494. // TODO: wait for https://github.com/GoogleChrome/puppeteer/pull/2812
  495. // update autoreload interval
  496. // await content.evaluate(() => state.ms = 250)
  497. })
  498. it('test ajax autoreload with non UTF-8 encoding and inactive tab', async () => {
  499. t.equal(
  500. await content.evaluate(() =>
  501. document.querySelector('#_html p').innerText.trim()
  502. ),
  503. '你好',
  504. 'first request'
  505. )
  506. // the initial interval is 1000
  507. await content.waitForTimeout(1300)
  508. t.equal(
  509. await content.evaluate(() =>
  510. document.querySelector('#_html p').innerText.trim()
  511. ),
  512. '你好',
  513. 'second request - xhr body is UTF-8 - should not trigger reload'
  514. )
  515. // the initial interval is 1000
  516. await content.waitForTimeout(1300)
  517. t.equal(
  518. await content.evaluate(() =>
  519. document.querySelector('#_html p').innerText.trim()
  520. ),
  521. '你好你好',
  522. 'third request - actual change'
  523. )
  524. // popup
  525. await popup.bringToFront()
  526. // the initial interval is 1000
  527. await content.waitForTimeout(1300)
  528. await content.bringToFront()
  529. t.equal(
  530. await content.evaluate(() =>
  531. document.querySelector('#_html p').innerText.trim()
  532. ),
  533. '你好你好你好',
  534. 'fourth request - should reload inactive tab'
  535. )
  536. })
  537. })
  538. }