popup-options.js 16 KB

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