popup-options.js 16 KB

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