瀏覽代碼

:art: #15 add puppeteer for jest

Van 6 年之前
父節點
當前提交
0abc27233b
共有 7 個文件被更改,包括 512 次插入47 次删除
  1. 35 0
      __test__/util/textareaPosition.spec.ts
  2. 6 28
      demo/demo.js
  3. 4 6
      demo/index.html
  4. 463 11
      package-lock.json
  5. 2 0
      package.json
  6. 1 1
      src/ts/hint/index.ts
  7. 1 1
      src/ts/preview/index.ts

+ 35 - 0
__test__/util/textareaPosition.spec.ts

@@ -0,0 +1,35 @@
+import puppeteer from 'puppeteer'
+
+describe('use puppeteer to test getTextareaPosition', () => {
+    let browser: any
+    let page: any
+    beforeAll(async () => {
+        browser = await puppeteer.launch()
+        page = await browser.newPage()
+        await Promise.all([
+            page.coverage.startJSCoverage(),
+            page.coverage.startCSSCoverage(),
+        ])
+        await page.goto('http://localhost:9000/demo/')
+    })
+
+    it('getTextareaPosition', async () => {
+        await page.evaluate(() => {
+            // @ts-ignore
+            vditorTest.setValue('vditorvditorvditorvditorvditorvditorvditorvditorvditorvditorvditorvditor for jest puppeteer :')
+        })
+
+        await page.waitFor(1000)
+
+        let text = await page.evaluate(() => {
+            // @ts-ignore
+            return vditorTest.vditor.hint.element.getAttribute('style')
+        })
+        expect(text).toContain('top: -65px;')
+        expect(text).toContain('left: 173px;')
+    })
+
+    afterAll(async () => {
+        await browser.close()
+    })
+})

+ 6 - 28
demo/demo.js

@@ -43,8 +43,9 @@ const LazyLoadImage = () => {
   }
 }
 
-const vditor2 = new Vditor('vditor2', {
+new Vditor('vditor', {
   counter: 100,
+  height: 300,
   editorName: 'vditor',
   tab: '  ',
   upload: {
@@ -69,10 +70,11 @@ const vditor2 = new Vditor('vditor2', {
   },
 })
 
-const vditor = new Vditor('vditor', {
+
+window.vditorTest = new Vditor('vditorTest', {
   cache: false,
   height: 200,
-  width: '50%',
+  width: 500,
   counter: 100,
   resize: {
     enable: true,
@@ -146,28 +148,4 @@ const vditor = new Vditor('vditor', {
     },
     'strike',
   ],
-})
-
-vditor.html2md('<h2>Hi</h2>').then(mdValue => {console.log(mdValue)})
-vditor.insertValue('Hi, Vditor!')
-vditor.focus()
-console.log('vditor.getValue(): ' + vditor.getValue())
-vditor.setSelection(4, 10)
-console.log('vditor.getSelection(): ' + vditor.getSelection())
-// setTimeout(() => {
-//   vditor.setValue('Hi, Markdown!')
-//   vditor.renderPreview()
-//   vditor.disabled()
-// }, 3000)
-//
-// setTimeout(() => {
-//   vditor.enable()
-//   vditor.setSelection(4, 12)
-//   vditor.deleteValue()
-// }, 6000)
-//
-// setTimeout(() => {
-//   vditor.setSelection(0, 4)
-//   vditor.updateValue('Welcome')
-//   vditor.blur()
-// }, 9000)
+})

+ 4 - 6
demo/index.html

@@ -38,20 +38,18 @@
     <link href="dist/demo.css" rel="stylesheet">
     <!-- webpack 编译 -->
     <script src="dist/demo.js" defer></script>
-    <!-- 静态文件引入文件 -->
-    <!--<link href="../dist/index.classic.css" rel="stylesheet">-->
 </head>
 <body>
-<h2>默认编辑器</h2>
-<div id="vditor2">
+<h2>vditor for you</h2>
+<div id="vditor">
     <h1>Vditor</h1>
     <ul>
         <li>foo</li>
         <li>bar</li>
     </ul>
 </div>
-<h2>自定义编辑器</h2>
-<div id="vditor"></div>
+<h2>vditor for jest puppeteer</h2>
+<div id="vditorTest"></div>
 <!-- 静态文件引入文件 -->
 <!--<script src="../dist/index.min.js"></script>-->
 <!--<script src="demo.js"></script>-->

+ 463 - 11
package-lock.json

@@ -991,6 +991,275 @@
         "to-fast-properties": "^2.0.0"
       }
     },
+    "@jest/console": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.3.0.tgz",
+      "integrity": "sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA==",
+      "dev": true,
+      "requires": {
+        "@jest/source-map": "^24.3.0",
+        "@types/node": "*",
+        "chalk": "^2.0.1",
+        "slash": "^2.0.0"
+      }
+    },
+    "@jest/fake-timers": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.3.0.tgz",
+      "integrity": "sha512-rHwVI17dGMHxHzfAhnZ04+wFznjFfZ246QugeBnbiYr7/bDosPD2P1qeNjWnJUUcfl0HpS6kkr+OB/mqSJxQFg==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.3.0",
+        "@types/node": "*",
+        "jest-message-util": "^24.3.0",
+        "jest-mock": "^24.3.0"
+      },
+      "dependencies": {
+        "jest-message-util": {
+          "version": "24.3.0",
+          "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.3.0.tgz",
+          "integrity": "sha512-lXM0YgKYGqN5/eH1NGw4Ix+Pk2I9Y77beyRas7xM24n+XTTK3TbT0VkT3L/qiyS7WkW0YwyxoXnnAaGw4hsEDA==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "@jest/test-result": "^24.3.0",
+            "@jest/types": "^24.3.0",
+            "@types/stack-utils": "^1.0.1",
+            "chalk": "^2.0.1",
+            "micromatch": "^3.1.10",
+            "slash": "^2.0.0",
+            "stack-utils": "^1.0.1"
+          }
+        },
+        "jest-mock": {
+          "version": "24.3.0",
+          "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.3.0.tgz",
+          "integrity": "sha512-AhAo0qjbVWWGvcbW5nChFjR0ObQImvGtU6DodprNziDOt+pP0CBdht/sYcNIOXeim8083QUi9bC8QdKB8PTK4Q==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^24.3.0"
+          }
+        }
+      }
+    },
+    "@jest/source-map": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz",
+      "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0",
+        "graceful-fs": "^4.1.15",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
+          "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/test-result": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.3.0.tgz",
+      "integrity": "sha512-j7UZ49T8C4CVipEY99nLttnczVTtLyVzFfN20OiBVn7awOs0U3endXSTq7ouPrLR5y4YjI5GDcbcvDUjgeamzg==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.3.0",
+        "@jest/types": "^24.3.0",
+        "@types/istanbul-lib-coverage": "^1.1.0"
+      }
+    },
+    "@jest/transform": {
+      "version": "24.3.1",
+      "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.3.1.tgz",
+      "integrity": "sha512-PpjylI5goT4Si69+qUjEeHuKjex0LjjrqJzrMYzlOZn/+SCumGKuGC0UQFeEPThyGsFvWH1Q4gj0R66eOHnIpw==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/types": "^24.3.0",
+        "babel-plugin-istanbul": "^5.1.0",
+        "chalk": "^2.0.1",
+        "convert-source-map": "^1.4.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graceful-fs": "^4.1.15",
+        "jest-haste-map": "^24.3.1",
+        "jest-regex-util": "^24.3.0",
+        "jest-util": "^24.3.0",
+        "micromatch": "^3.1.10",
+        "realpath-native": "^1.1.0",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.1",
+        "write-file-atomic": "2.4.1"
+      },
+      "dependencies": {
+        "@cnakazawa/watch": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz",
+          "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==",
+          "dev": true,
+          "requires": {
+            "exec-sh": "^0.3.2",
+            "minimist": "^1.2.0"
+          }
+        },
+        "callsites": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
+          "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
+          "dev": true
+        },
+        "exec-sh": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz",
+          "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==",
+          "dev": true
+        },
+        "jest-haste-map": {
+          "version": "24.3.1",
+          "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.3.1.tgz",
+          "integrity": "sha512-OTMQle+astr1lWKi62Ccmk2YWn6OtUoU/8JpJdg8zdsnpFIry/k0S4sQ4nWocdM07PFdvqcthWc78CkCE6sXvA==",
+          "dev": true,
+          "requires": {
+            "@jest/types": "^24.3.0",
+            "fb-watchman": "^2.0.0",
+            "graceful-fs": "^4.1.15",
+            "invariant": "^2.2.4",
+            "jest-serializer": "^24.3.0",
+            "jest-util": "^24.3.0",
+            "jest-worker": "^24.3.1",
+            "micromatch": "^3.1.10",
+            "sane": "^4.0.3"
+          }
+        },
+        "jest-regex-util": {
+          "version": "24.3.0",
+          "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.3.0.tgz",
+          "integrity": "sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==",
+          "dev": true
+        },
+        "jest-serializer": {
+          "version": "24.3.0",
+          "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.3.0.tgz",
+          "integrity": "sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg==",
+          "dev": true
+        },
+        "jest-util": {
+          "version": "24.3.0",
+          "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.3.0.tgz",
+          "integrity": "sha512-eKIAC+MTKWZthUUVOwZ3Tc5a0cKMnxalQHr6qZ4kPzKn6k09sKvsmjCygqZ1SxVVfUKoa8Sfn6XDv9uTJ1iXTg==",
+          "dev": true,
+          "requires": {
+            "@jest/console": "^24.3.0",
+            "@jest/fake-timers": "^24.3.0",
+            "@jest/source-map": "^24.3.0",
+            "@jest/test-result": "^24.3.0",
+            "@jest/types": "^24.3.0",
+            "@types/node": "*",
+            "callsites": "^3.0.0",
+            "chalk": "^2.0.1",
+            "graceful-fs": "^4.1.15",
+            "is-ci": "^2.0.0",
+            "mkdirp": "^0.5.1",
+            "slash": "^2.0.0",
+            "source-map": "^0.6.0"
+          }
+        },
+        "jest-worker": {
+          "version": "24.3.1",
+          "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.3.1.tgz",
+          "integrity": "sha512-ZCoAe/iGLzTJvWHrO8fyx3bmEQhpL16SILJmWHKe8joHhyF3z00psF1sCRT54DoHw5GJG0ZpUtGy+ylvwA4haA==",
+          "dev": true,
+          "requires": {
+            "@types/node": "*",
+            "merge-stream": "^1.0.1",
+            "supports-color": "^6.1.0"
+          }
+        },
+        "sane": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npmjs.org/sane/-/sane-4.0.3.tgz",
+          "integrity": "sha512-hSLkC+cPHiBQs7LSyXkotC3UUtyn8C4FMn50TNaacRyvBlI+3ebcxMpqckmTdtXVtel87YS7GXN3UIOj7NiGVQ==",
+          "dev": true,
+          "requires": {
+            "@cnakazawa/watch": "^1.0.3",
+            "anymatch": "^2.0.0",
+            "capture-exit": "^1.2.0",
+            "exec-sh": "^0.3.2",
+            "execa": "^1.0.0",
+            "fb-watchman": "^2.0.0",
+            "micromatch": "^3.1.4",
+            "minimist": "^1.1.1",
+            "walker": "~1.0.5"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "@jest/types": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.3.0.tgz",
+      "integrity": "sha512-VoO1F5tU2n/93QN/zaZ7Q8SeV/Rj+9JJOgbvKbBwy4lenvmdj1iDaQEPXGTKrO6OSvDeb2drTFipZJYxgo6kIQ==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "^1.1.0",
+        "@types/yargs": "^12.0.9"
+      }
+    },
+    "@types/babel__core": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz",
+      "integrity": "sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "@types/babel__generator": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz",
+      "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__template": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz",
+      "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
     "@types/babel__traverse": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz",
@@ -1000,6 +1269,12 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "@types/istanbul-lib-coverage": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz",
+      "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==",
+      "dev": true
+    },
     "@types/jest": {
       "version": "24.0.9",
       "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.9.tgz",
@@ -1015,12 +1290,39 @@
       "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
       "dev": true
     },
+    "@types/node": {
+      "version": "11.11.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.0.tgz",
+      "integrity": "sha512-D5Rt+HXgEywr3RQJcGlZUCTCx1qVbCZpVk3/tOOA6spLNZdGm8BU+zRgdRYDoF1pO3RuXLxADzMrF903JlQXqg==",
+      "dev": true
+    },
+    "@types/puppeteer": {
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-1.12.2.tgz",
+      "integrity": "sha512-EGfxdNxqsEQiY6Ce+4rRD8PsDD18b5FWR+J/gWX7J/UKNRk1Pi9bircx0oADMNF2RdbyzmC+7TU95nwnerFwlA==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz",
       "integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==",
       "dev": true
     },
+    "@types/stack-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+      "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+      "dev": true
+    },
+    "@types/yargs": {
+      "version": "12.0.9",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.9.tgz",
+      "integrity": "sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==",
+      "dev": true
+    },
     "@webassemblyjs/ast": {
       "version": "1.7.11",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz",
@@ -1251,6 +1553,15 @@
       "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
       "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw=="
     },
+    "agent-base": {
+      "version": "4.2.1",
+      "resolved": "http://registry.npm.taobao.org/agent-base/download/agent-base-4.2.1.tgz",
+      "integrity": "sha1-2J5ZmfeXh1Z0wH2H8mD8Qeg+jKk=",
+      "dev": true,
+      "requires": {
+        "es6-promisify": "^5.0.0"
+      }
+    },
     "ajv": {
       "version": "6.7.0",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz",
@@ -1611,13 +1922,16 @@
       }
     },
     "babel-jest": {
-      "version": "24.1.0",
-      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.1.0.tgz",
-      "integrity": "sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw==",
+      "version": "24.3.1",
+      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.3.1.tgz",
+      "integrity": "sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg==",
       "dev": true,
       "requires": {
+        "@jest/transform": "^24.3.1",
+        "@jest/types": "^24.3.0",
+        "@types/babel__core": "^7.1.0",
         "babel-plugin-istanbul": "^5.1.0",
-        "babel-preset-jest": "^24.1.0",
+        "babel-preset-jest": "^24.3.0",
         "chalk": "^2.4.2",
         "slash": "^2.0.0"
       }
@@ -1646,22 +1960,22 @@
       }
     },
     "babel-plugin-jest-hoist": {
-      "version": "24.2.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.2.0.tgz",
-      "integrity": "sha512-U63Kx0ZbB6TFjcmRRZvkQfkBlh8beJ1q8CsO+cl4uAlr7bLZM0isvQP369fUEZeJJr/1yqRplzHj14TAmQ1r0Q==",
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz",
+      "integrity": "sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w==",
       "dev": true,
       "requires": {
         "@types/babel__traverse": "^7.0.6"
       }
     },
     "babel-preset-jest": {
-      "version": "24.1.0",
-      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz",
-      "integrity": "sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw==",
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz",
+      "integrity": "sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw==",
       "dev": true,
       "requires": {
         "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
-        "babel-plugin-jest-hoist": "^24.1.0"
+        "babel-plugin-jest-hoist": "^24.3.0"
       }
     },
     "balanced-match": {
@@ -3373,6 +3687,21 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "es6-promise": {
+      "version": "4.2.6",
+      "resolved": "http://registry.npm.taobao.org/es6-promise/download/es6-promise-4.2.6.tgz",
+      "integrity": "sha1-toXt2CWIhjZepitX0w3ij63Nl08=",
+      "dev": true
+    },
+    "es6-promisify": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "^4.0.3"
+      }
+    },
     "es6-templates": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz",
@@ -3716,6 +4045,18 @@
         }
       }
     },
+    "extract-zip": {
+      "version": "1.6.7",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.2",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.1",
+        "yauzl": "2.4.1"
+      }
+    },
     "extsprintf": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -3760,6 +4101,15 @@
         "bser": "^2.0.0"
       }
     },
+    "fd-slicer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "dev": true,
+      "requires": {
+        "pend": "~1.2.0"
+      }
+    },
     "figgy-pudding": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
@@ -5131,6 +5481,33 @@
       "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
       "dev": true
     },
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "http://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=",
+      "dev": true,
+      "requires": {
+        "agent-base": "^4.1.0",
+        "debug": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "http://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz",
+          "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "http://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz",
+          "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=",
+          "dev": true
+        }
+      }
+    },
     "iconv-lite": {
       "version": "0.4.23",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
@@ -7687,6 +8064,12 @@
         "sha.js": "^2.4.8"
       }
     },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -8250,6 +8633,12 @@
       "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
       "dev": true
     },
+    "progress": {
+      "version": "2.0.3",
+      "resolved": "http://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz",
+      "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=",
+      "dev": true
+    },
     "promise-inflight": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@@ -8276,6 +8665,12 @@
         "ipaddr.js": "1.8.0"
       }
     },
+    "proxy-from-env": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+      "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
+      "dev": true
+    },
     "prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -8345,6 +8740,54 @@
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
     },
+    "puppeteer": {
+      "version": "1.13.0",
+      "resolved": "http://registry.npm.taobao.org/puppeteer/download/puppeteer-1.13.0.tgz",
+      "integrity": "sha1-GHzPXtXK8I7RKRsmLQM8w2S/iKs=",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "extract-zip": "^1.6.6",
+        "https-proxy-agent": "^2.2.1",
+        "mime": "^2.0.3",
+        "progress": "^2.0.1",
+        "proxy-from-env": "^1.0.0",
+        "rimraf": "^2.6.1",
+        "ws": "^6.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "http://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz",
+          "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "mime": {
+          "version": "2.4.0",
+          "resolved": "http://registry.npm.taobao.org/mime/download/mime-2.4.0.tgz",
+          "integrity": "sha1-4FH9iBNYWF8yed8zP+aU2gvP/dY=",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "http://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz",
+          "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=",
+          "dev": true
+        },
+        "ws": {
+          "version": "6.2.0",
+          "resolved": "http://registry.npm.taobao.org/ws/download/ws-6.2.0.tgz",
+          "integrity": "sha1-E4BtmROypfPLubpHtWPAAsvHxSY=",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0"
+          }
+        }
+      }
+    },
     "q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -11084,6 +11527,15 @@
         "camelcase": "^5.0.0",
         "decamelize": "^1.2.0"
       }
+    },
+    "yauzl": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "dev": true,
+      "requires": {
+        "fd-slicer": "~1.0.1"
+      }
     }
   }
 }

+ 2 - 0
package.json

@@ -17,6 +17,7 @@
     "@babel/core": "^7.3.4",
     "@babel/preset-env": "^7.3.4",
     "@types/jest": "^24.0.9",
+    "@types/puppeteer": "^1.12.2",
     "autoprefixer": "^9.4.6",
     "babel-loader": "^8.0.5",
     "clean-webpack-plugin": "^1.0.1",
@@ -30,6 +31,7 @@
     "on-build-webpack": "^0.1.0",
     "optimize-css-assets-webpack-plugin": "^5.0.1",
     "postcss-loader": "^3.0.0",
+    "puppeteer": "^1.13.0",
     "sass-loader": "^7.1.0",
     "ts-jest": "^24.0.0",
     "ts-loader": "^5.3.3",

+ 1 - 1
src/ts/hint/index.ts

@@ -30,7 +30,7 @@ export class Hint {
         } else {
             if (atKey !== undefined && this.hint.at) {
                 clearTimeout(this.timeId);
-                this.timeId = setTimeout(() => {
+                this.timeId = window.setTimeout(() => {
                     this.genHTML(this.hint.at(atKey), atKey);
                 }, this.hint.delay);
             }

+ 1 - 1
src/ts/preview/index.ts

@@ -30,7 +30,7 @@ export class Preview {
 
         if (vditor.options.preview.url) {
             clearTimeout(vditor.mdTimeoutId);
-            vditor.mdTimeoutId = setTimeout(() => {
+            vditor.mdTimeoutId = window.setTimeout(() => {
                 const xhr = new XMLHttpRequest();
                 xhr.open("POST", vditor.options.preview.url);
                 xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");