Best JavaScript code snippet using testcafe
PathMonitor.spec.js
Source:PathMonitor.spec.js  
...24      const servePath = path.join(TEST_DATA, "example-project");25      instance = new PathMonitor({ servePath });26      sinon.spy(instance, "loadHtmlAssetAndPopulate");27      const assetPath = "/stuff.html";28      const loadPromise = instance.loadAsset(assetPath);29      await expect(loadPromise, "to be fulfilled");30      expect(instance.loadHtmlAssetAndPopulate.calledOnce, "to be true");31    });32    it("should load assets (javascript)", async () => {33      const servePath = path.join(TEST_DATA, "example-project");34      instance = new PathMonitor({ servePath });35      sinon.spy(instance, "loadJsAssetAndPopulate");36      const assetPath = "/stuff.js";37      const loadPromise = instance.loadAsset(assetPath);38      await expect(loadPromise, "to be fulfilled");39      expect(instance.loadJsAssetAndPopulate.calledOnce, "to be true");40    });41    it("should persist the loaded asset", async () => {42      const servePath = path.join(TEST_DATA, "example-project");43      instance = new PathMonitor({ servePath });44      const assetPath = "/stuff.html";45      const asset = await instance.loadAsset(assetPath);46      expect(instance.loadedByAssetPath[assetPath], "to be", asset);47    });48    it("should deduplicate load requests", async () => {49      const servePath = path.join(TEST_DATA, "example-project");50      instance = new PathMonitor({ servePath });51      const assetPath = "/stuff.html";52      const loadPromise = instance.loadAsset(assetPath);53      const secondLoadPromise = instance.loadAsset(assetPath);54      try {55        expect(secondLoadPromise, "to equal", loadPromise);56      } finally {57        await loadPromise;58      }59    });60    it("should load any dirtied asset requests", async () => {61      const servePath = path.join(TEST_DATA, "example-relations");62      instance = new PathMonitor({ servePath });63      sinon.spy(instance, "loadAssetOnly");64      const assetPath = "/stuff.css";65      instance.loadedByAssetPath[assetPath] = {66        asset: (await instance.assetGraph.loadAssets(assetPath))[0],67        dirty: true68      };69      const record = await instance.loadAsset(assetPath);70      expect(instance.loadAssetOnly.calledOnce, "to be true");71      // check the cache record was not re-created72      expect(instance.loadedByAssetPath[assetPath], "to be", record);73    });74    it("should not load the asset if it is already loaded", () => {75      const servePath = path.join(TEST_DATA, "example-project");76      instance = new PathMonitor({ servePath });77      const assetPath = "/stuff.html";78      instance.loadedByAssetPath[assetPath] = true;79      const loadPromise = instance.loadAsset(assetPath);80      return expect(81        instance.promiseByAssetPath[assetPath],82        "to be undefined"83      ).then(() => loadPromise);84    });85    it("should ignore any assets if that do not exist", () => {86      const servePath = path.join(TEST_DATA, "example-project");87      instance = new PathMonitor({ servePath });88      const assetPath = "/stuff.ico";89      const loadPromise = instance.loadAsset(assetPath);90      return expect(instance.promiseByAssetPath[assetPath], "to be defined")91        .then(() => loadPromise)92        .then(() => {93          expect(instance.promiseByAssetPath[assetPath], "to be undefined");94        });95    });96    describe("with a previously loaded asset", () => {97      it("should return promises from subsequent calls", async () => {98        const servePath = path.join(TEST_DATA, "example-project");99        instance = new PathMonitor({ servePath });100        const assetPath = "/stuff.html";101        const record = await instance.loadAsset(assetPath);102        const maybePromise = instance.loadAsset(assetPath);103        expect(maybePromise, "to be a", "Promise");104        expect(await maybePromise, "to equal", record);105      });106    });107  });108  describe("#loadAssetOnly", () => {109    it("should load assets", async () => {110      const servePath = path.join(TEST_DATA, "example-relations");111      instance = new PathMonitor({ servePath });112      const assetPath = "/stuff.css";113      await instance.loadHtmlAssetAndPopulate(assetPath);114      expect(instance.assetGraph._assets.size, "to equal", 1);115    });116    it("should register the promise while it is loading", () => {117      const servePath = path.join(TEST_DATA, "example-relations");118      instance = new PathMonitor({ servePath });119      const assetPath = "/stuff.css";120      const loadPromise = instance.loadAssetOnly(assetPath);121      return expect(122        instance.promiseByAssetPath[assetPath],123        "to equal",124        loadPromise125      ).then(() => loadPromise);126    });127    describe("with a dirtied asset", () => {128      it("should reload the asset", async () => {129        const assetPath = "/stuff.css";130        const servePath = path.join(TEST_DATA, "example-relations");131        instance = new PathMonitor({ servePath });132        await instance.loadAssetOnly(assetPath);133        instance.loadedByAssetPath[assetPath].asset.text = "EEK";134        instance.loadedByAssetPath[assetPath].dirty = true;135        await instance.loadAssetOnly(assetPath);136        const { asset } = instance.loadedByAssetPath[assetPath];137        expect(asset.text, "not to contain", "EEK");138      });139      it("should clear the dirty flag", async () => {140        const assetPath = "/stuff.css";141        const servePath = path.join(TEST_DATA, "example-relations");142        instance = new PathMonitor({ servePath });143        await instance.loadAssetOnly(assetPath);144        instance.loadedByAssetPath[assetPath].asset.text = "EEK";145        instance.loadedByAssetPath[assetPath].dirty = true;146        const record = await instance.loadAssetOnly(assetPath);147        expect(record.dirty, "to be false");148      });149    });150  });151  describe("#loadHtmlAssetAndPopulate", () => {152    it("should populate assets", async () => {153      const servePath = path.join(TEST_DATA, "example-relations");154      instance = new PathMonitor({ servePath });155      const assetPath = "/stuff.html";156      await instance.loadHtmlAssetAndPopulate(assetPath);157      expect(instance.assetGraph._assets.size, "to be greater than", 1);158    });159    it("should register the promise while it is populating", async () => {160      const servePath = path.join(TEST_DATA, "example-project");161      instance = new PathMonitor({ servePath });162      const assetPath = "/stuff.html";163      const loadPromise = instance.loadHtmlAssetAndPopulate(assetPath);164      return expect(165        instance.promiseByAssetPath[assetPath],166        "to equal",167        loadPromise168      ).then(() => loadPromise);169    });170    it("should deduplicate populate requests", async () => {171      const servePath = path.join(TEST_DATA, "example-project");172      instance = new PathMonitor({ servePath });173      const assetPath = "/stuff.html";174      const populatePromise = instance.loadHtmlAssetAndPopulate(assetPath);175      const secondPopulatePromise = instance.loadHtmlAssetAndPopulate(176        assetPath177      );178      try {179        expect(secondPopulatePromise, "to equal", populatePromise);180      } finally {181        await populatePromise;182      }183    });184    it("should include type JavaScript", () => {185      const servePath = path.join(TEST_DATA, "example-relations");186      instance = new PathMonitor({ servePath });187      const assetPath = "/stuff.html";188      return expect(189        () => instance.loadHtmlAssetAndPopulate(assetPath),190        "to be fulfilled"191      ).then(() => {192        expect(193          instance.assetGraph.findAssets({ type: "JavaScript" }),194          "not to be empty"195        );196      });197    });198    it("should include type Css", () => {199      const servePath = path.join(TEST_DATA, "example-relations");200      instance = new PathMonitor({ servePath });201      const assetPath = "/stuff.html";202      return expect(203        () => instance.loadHtmlAssetAndPopulate(assetPath),204        "to be fulfilled"205      ).then(() => {206        expect(207          instance.assetGraph.findAssets({ type: "Css" }),208          "not to be empty"209        );210      });211    });212    it("should work for script of type module", () => {213      const servePath = path.join(TEST_DATA, "example-module");214      instance = new PathMonitor({ servePath });215      const assetPath = "/stuff.html";216      return expect(217        () => instance.loadHtmlAssetAndPopulate(assetPath),218        "to be fulfilled"219      ).then(() => {220        expect(221          instance.assetGraph.findAssets({ type: "JavaScript" }),222          "not to be empty"223        );224      });225    });226    it('should work for modules within a directory containg an "@"', async () => {227      const servePath = path.join(TEST_DATA, "example-index@");228      instance = new PathMonitor({ servePath });229      const assetPath = "/index.html";230      const record = await instance.loadHtmlAssetAndPopulate(assetPath);231      expect(record, "not to be null");232    });233    it("should ignore population failures", async () => {234      const assetPath = "/stuff.html";235      const servePath = path.join(TEST_DATA, "example-badmodule");236      instance = new PathMonitor({ servePath });237      const record = await instance.loadHtmlAssetAndPopulate(assetPath);238      expect(record, "not to be null");239    });240    it("should work for nested scripts", () => {241      const servePath = path.join(TEST_DATA, "example-module");242      instance = new PathMonitor({ servePath });243      const assetPath = "/stuff.html";244      return expect(245        () => instance.loadHtmlAssetAndPopulate(assetPath),246        "to be fulfilled"247      ).then(() => {248        const assets = instance.assetGraph.findAssets({249          type: "JavaScript"250        });251        expect(assets, "to satisfy", [252          {253            url: normalizeUrl(`file://${servePath}/stuff.js`)254          },255          {256            url: normalizeUrl(`file://${servePath}/otherstuff.js`)257          }258        ]);259      });260    });261    it("should rewrite inline script imports", async () => {262      const assetPath = "/index.html";263      const servePath = path.join(TEST_DATA, "example-image");264      const nodeModulesPath = toNodeModulesPath(servePath);265      const importResolver = new ImportResolver({ servePath, nodeModulesPath });266      instance = new PathMonitor({ importResolver, servePath });267      const { asset } = await instance.loadHtmlAssetAndPopulate(assetPath);268      expect(269        asset.text,270        "to equal snapshot",271        expect.unindent`272          <html><head></head><body>273                  <script type="module">import { lasercat } from '/__node_modules/catimages/index.js';274          const img = document.createElement('img');275          img.src = lasercat;276          document.body.appendChild(img);</script>277          ${"    "}278          </body></html>279        `280      );281    });282    it("should ignore node resolution that returns a non-HTML asset", async () => {283      const assetPath = "/stuff.html";284      const servePath = path.join(TEST_DATA, "example-badresolve");285      instance = new PathMonitor({ servePath });286      const record = await instance.loadHtmlAssetAndPopulate(assetPath);287      expect(record, "to be null");288    });289    describe("with a dirtied asset", () => {290      it("should reload the asset", async () => {291        const assetPath = "/stuff.html";292        const servePath = path.join(TEST_DATA, "example-module");293        instance = new PathMonitor({ servePath });294        await instance.loadHtmlAssetAndPopulate(assetPath);295        instance.loadedByAssetPath[assetPath].asset.text = "EEK";296        instance.loadedByAssetPath[assetPath].dirty = true;297        await instance.loadHtmlAssetAndPopulate(assetPath);298        const { asset } = instance.loadedByAssetPath[assetPath];299        expect(asset.text, "not to contain", "EEK");300      });301    });302  });303  describe("#loadJsAssetAndPopulate", () => {304    it("should rewrite node_modules imports with double quote", async () => {305      const assetPath = "/preact.js";306      const servePath = path.join(TEST_DATA, "example-npm");307      const nodeModulesPath = toNodeModulesPath(servePath);308      const importResolver = new ImportResolver({ servePath, nodeModulesPath });309      instance = new PathMonitor({ importResolver, servePath });310      const { asset } = await instance.loadJsAssetAndPopulate(assetPath);311      expect(312        asset.text,313        "to equal snapshot",314        expect.unindent`315          import { html, render } from "/__node_modules/htm/preact/index.module.js";316          render(317            html\`318              <h1>Hello World</h1>319            \`,320            document.getElementById("app-root")321          );322        `323      );324    });325    it("should rewrite node_modules imports with single quote", async () => {326      const assetPath = "/react-window.js";327      const servePath = path.join(TEST_DATA, "example-npm");328      const nodeModulesPath = toNodeModulesPath(servePath);329      const importResolver = new ImportResolver({ servePath, nodeModulesPath });330      instance = new PathMonitor({ importResolver, servePath });331      const { asset } = await instance.loadJsAssetAndPopulate(assetPath);332      expect(333        asset.text,334        "to equal snapshot",335        expect.unindent`336          // prettier-ignore337          // eslint-disable-next-line no-unused-vars338          import { VariableSizeGrid } from '/__node_modules/react-window/dist/index.esm.js';339        `340      );341    });342    it("should rewrite node_modules imports in a workspace", async () => {343      const assetPath = "/index.js";344      const servePath = path.join(TEST_DATA, "example-workspaces", "demo");345      const nodeModulesPath = toNodeModulesPath(servePath);346      const importResolver = new ImportResolver({347        isMonorepo: true,348        servePath,349        nodeModulesPath350      });351      instance = new PathMonitor({ importResolver, servePath });352      const { asset } = await instance.loadJsAssetAndPopulate(assetPath);353      expect(354        asset.text,355        "to equal snapshot",356        expect.unindent`357          // eslint-disable-next-line import/no-named-default358          import { default as hello } from "/__node_modules/~/1/packages/utils/index.js";359          console.log(hello);360        `361      );362    });363    it("should pass through relative imports", async () => {364      const assetPath = "/stuff.js";365      const servePath = path.join(TEST_DATA, "example-module");366      const nodeModulesPath = toNodeModulesPath(servePath);367      const diskPath = path.join(servePath, assetPath.slice(1));368      const importResolver = new ImportResolver({ servePath, nodeModulesPath });369      instance = new PathMonitor({ importResolver, servePath });370      const record = await instance.loadJsAssetAndPopulate(assetPath);371      expect(record.asset, "to satisfy", {372        text: fs.readFileSync(diskPath, "utf8")373      });374    });375    describe("with a dirtied asset", () => {376      it("should reload the asset", async () => {377        const assetPath = "/stuff.js";378        const servePath = path.join(TEST_DATA, "example-module");379        const nodeModulesPath = toNodeModulesPath(servePath);380        const importResolver = new ImportResolver({381          servePath,382          nodeModulesPath383        });384        instance = new PathMonitor({ importResolver, servePath });385        await instance.loadJsAssetAndPopulate(assetPath);386        instance.loadedByAssetPath[assetPath].asset.text = "EEK";387        instance.loadedByAssetPath[assetPath].dirty = true;388        await instance.loadJsAssetAndPopulate(assetPath);389        const { asset } = instance.loadedByAssetPath[assetPath];390        expect(asset.text, "not to contain", "EEK");391      });392    });393    describe("with an asset that has delicate code", () => {394      it("should use the raw text of the asset", async () => {395        const assetPath = "/example.js";396        const servePath = path.join(TEST_DATA, "example-delicate");397        const nodeModulesPath = toNodeModulesPath(servePath);398        const importResolver = new ImportResolver({399          servePath,400          nodeModulesPath401        });402        instance = new PathMonitor({ importResolver, servePath });403        await instance.loadJsAssetAndPopulate(assetPath);404        const { asset } = instance.loadedByAssetPath[assetPath];405        expect(406          asset.text,407          "to equal snapshot",408          expect.unindent`409          /* eslint-disable */410          // prettier-ignore411          const MyComponent = () => {412              return /*#__PURE__*/React.createElement(App, null);413          };414        `415        );416      });417      it("should use the raw text of the asset when rewriting", async () => {418        const assetPath = "/rewrite.js";419        const servePath = path.join(TEST_DATA, "example-delicate");420        const nodeModulesPath = toNodeModulesPath(servePath);421        const importResolver = new ImportResolver({422          servePath,423          nodeModulesPath424        });425        instance = new PathMonitor({ importResolver, servePath });426        await instance.loadJsAssetAndPopulate(assetPath);427        const { asset } = instance.loadedByAssetPath[assetPath];428        // eslint-disable-next-line no-unused-expressions429        asset.text; // simulate first access430        expect(431          asset.text,432          "to equal snapshot",433          expect.unindent`434          /* eslint-disable */435          import { html, render } from "/__node_modules/htm/preact/index.module.js";436          // prettier-ignore437          const MyComponent = () => {438              return /*#__PURE__*/React.createElement(App, null);439          };440        `441        );442      });443    });444  });445  describe("#getAsset", () => {446    it("should return a loaded asset", async () => {447      const assetPath = "/stuff.html";448      const servePath = path.join(TEST_DATA, "example-project");449      const diskPath = path.join(servePath, assetPath.slice(1));450      instance = new PathMonitor({ servePath });451      await instance.loadAsset(assetPath);452      const [asset] = instance.assetGraph.findAssets({453        url: normalizeUrl(`file://${diskPath}`)454      });455      const record = instance.getAsset(assetPath);456      expect(record, "to satisfy", {457        asset: expect.it("to be", asset),458        dirty: false459      });460    });461    it("should return a dirtied asset", async () => {462      const assetPath = "/stuff.html";463      const servePath = path.join(TEST_DATA, "example-project");464      instance = new PathMonitor({ servePath });465      await instance.loadAsset(assetPath);466      instance.loadedByAssetPath[assetPath].dirty = true;467      const record = instance.getAsset(assetPath);468      expect(record, "to be null");469    });470  });471  describe("#dirtyAsset", () => {472    it("should mark a loaded asset dirty", async () => {473      const assetPath = "/stuff.html";474      const servePath = path.join(TEST_DATA, "example-project");475      instance = new PathMonitor({ servePath });476      await instance.loadAsset(assetPath);477      instance.dirtyAsset(assetPath);478      const record = instance.loadedByAssetPath[assetPath];479      expect(record, "to satisfy", {480        dirty: true481      });482    });483  });484  describe("#addClient", () => {485    it("should mark a client with any unseen changes", async () => {486      const servePath = path.join(TEST_DATA, "example-relations");487      instance = new PathMonitor({ servePath });488      const assetPath = "/stuff.js";489      instance.orphanByAssetPath[assetPath] = true;490      const client = new Client({491        onReload: () => {492          throw new Error("should not occur");493        }494      });495      instance.addClient(client);496      expect(497        client.unseenChangesByAssetPath,498        "to equal",499        instance.orphanByAssetPath500      ).and("not to be", instance.orphanByAssetPath);501    });502  });503  describe("#linkClient", () => {504    it("should normalise any recorded client path", async () => {505      const servePath = path.join(TEST_DATA, "example-relations");506      instance = new PathMonitor({ servePath });507      sinon.spy(instance, "_linkClientHandleOrphans");508      const leafPath = "/stuff.html";509      await instance.loadAsset(leafPath);510      const assetPath = "/stuff.js";511      await instance.loadAsset(assetPath);512      const client = new Client({});513      client.clientState = "active";514      instance.linkClient(client, "/stuff");515      expect(instance.clientAssets.get(client), "to equal", "/stuff.html");516    });517    it("should notify the client of an unseen changes", async () => {518      const servePath = path.join(TEST_DATA, "example-relations");519      instance = new PathMonitor({ servePath });520      sinon.spy(instance, "_linkClientHandleOrphans");521      const leafPath = "/stuff.html";522      await instance.loadAsset(leafPath);523      const assetPath = "/stuff.js";524      await instance.loadAsset(assetPath);525      let onReloadCalled = false;526      const client = new Client({527        onReload: () => {528          onReloadCalled = true;529        }530      });531      client.unseenChangesByAssetPath[assetPath] = true;532      client.clientState = "active";533      instance.linkClient(client, leafPath);534      await instance._linkClientHandleOrphans.firstCall.returnValue;535      expect(onReloadCalled, "to be true");536    });537    it("should clear any unseen changes", async () => {538      const servePath = path.join(TEST_DATA, "example-relations");539      instance = new PathMonitor({ servePath });540      sinon.spy(instance, "_linkClientHandleOrphans");541      const leafPath = "/stuff.html";542      await instance.loadAsset(leafPath);543      const assetPath = "/stuff.js";544      await instance.loadAsset(assetPath);545      const client = new Client({546        onReload: () => {}547      });548      client.unseenChangesByAssetPath[assetPath] = true;549      client.clientState = "active";550      instance.linkClient(client, leafPath);551      await instance._linkClientHandleOrphans.firstCall.returnValue;552      expect(client.unseenChangesByAssetPath, "to equal", {});553    });554    describe("when permitting client side routing", () => {555      it("should normalise a missing client path", async () => {556        const servePath = path.join(TEST_DATA, "example-index");557        instance = new PathMonitor({558          servePath,559          permitClientSideRouting: true560        });561        sinon.spy(instance, "_linkClientHandleOrphans");562        const leafPath = "/index.html";563        await instance.loadAsset(leafPath);564        const client = new Client({});565        client.clientState = "active";566        instance.linkClient(client, "/stuff");567        expect(instance.clientAssets.get(client), "to equal", "/index.html");568      });569    });570  });571  describe("#notifyClientForFsPath", () => {572    it("should notify a client for a corresponding leaf asset", async () => {573      const servePath = path.join(TEST_DATA, "example-project");574      instance = new PathMonitor({ servePath });575      const assetPath = "/stuff.html";576      await instance.loadAsset(assetPath);577      let onReloadCalled = false;578      const client = new Client({579        onReload: () => {580          onReloadCalled = true;581        }582      });583      client.clientState = "active";584      instance.linkClient(client, assetPath);585      await instance.notifyClientForFsPath(586        path.join(servePath, assetPath.slice(1))587      );588      expect(onReloadCalled, "to be true");589    });590    it("should notify a client for a corresponding related asset", async () => {591      const servePath = path.join(TEST_DATA, "example-relations");592      instance = new PathMonitor({ servePath });593      const leafPath = "/stuff.html";594      await instance.loadAsset(leafPath);595      const assetPath = "/stuff.js";596      await instance.loadAsset(assetPath);597      let onReloadCalled = false;598      const client = new Client({599        pathMonitor: instance,600        onReload: () => {601          onReloadCalled = true;602        }603      });604      instance.addClient(client);605      client.clientState = "active";606      instance.linkClient(client, leafPath);607      await instance.notifyClientForFsPath(608        path.join(servePath, assetPath.slice(1))609      );610      expect(onReloadCalled, "to be true");611    });612    it("should wait for the resolution of any load promises", async () => {613      const servePath = path.join(TEST_DATA, "example-project");614      instance = new PathMonitor({ servePath });615      const assetPath = "/stuff.html";616      await instance.loadAsset(assetPath);617      // arrange for an outstanging load promise618      let resolvePromise;619      instance.promiseByAssetPath[assetPath] = new Promise(resolve => {620        resolvePromise = resolve;621      });622      // enable checking whether it resolved623      let sawResolution = false;624      instance625        .notifyClientForFsPath(path.join(servePath, assetPath.slice(1)))626        .then(() => (sawResolution = true));627      await waitImmediate();628      expect(sawResolution, "to be false");629      // now complete the pending load promise630      resolvePromise();631      await waitImmediate();632      expect(sawResolution, "to be true");633    });634    it("should record an unseen change if the asset was never loaded", async () => {635      const servePath = path.join(TEST_DATA, "example-relations");636      instance = new PathMonitor({ servePath });637      const assetPath = "/stuff.js";638      await instance.notifyClientForFsPath(639        path.join(servePath, assetPath.slice(1))640      );641      expect(instance.orphanByAssetPath, "to equal", {642        [assetPath]: true643      });644    });645    it("should record an unseen change if the asset was loaded", async () => {646      const servePath = path.join(TEST_DATA, "example-relations");647      instance = new PathMonitor({ servePath });648      const assetPath = "/stuff.js";649      await instance.loadAsset(assetPath);650      await instance.notifyClientForFsPath(651        path.join(servePath, assetPath.slice(1))652      );653      expect(instance.orphanByAssetPath, "to equal", {654        [assetPath]: true655      });656    });657    it("should record any changes on an unlinked client", async () => {658      const servePath = path.join(TEST_DATA, "example-relations");659      instance = new PathMonitor({ servePath });660      const leafAsset = "/stuff.html";661      await instance.loadAsset(leafAsset);662      const assetPath = "/stuff.js";663      await instance.loadAsset(assetPath);664      const client = new Client({665        onReload: () => {666          throw new Error("should not occur");667        }668      });669      instance.addClient(client);670      await instance.notifyClientForFsPath(671        path.join(servePath, assetPath.slice(1))672      );673      expect(client.unseenChangesByAssetPath, "to equal", {674        [assetPath]: true675      });676    });677    it("should mark the asset dirtied", async () => {678      const assetPath = "/stuff.js";679      const servePath = path.join(TEST_DATA, "example-relations");680      const diskPath = path.join(servePath, assetPath.slice(1));681      instance = new PathMonitor({ servePath });682      sinon.stub(instance, "dirtyAsset");683      await instance.loadAsset(assetPath);684      await instance.notifyClientForFsPath(diskPath);685      expect(instance.dirtyAsset.firstCall.args, "to satisfy", [assetPath]);686    });687    it("should ignore an orphaned related asset", async () => {688      const servePath = path.join(TEST_DATA, "example-relations");689      instance = new PathMonitor({ servePath });690      sinon.spy(instance, "informClients");691      const leafPath = "/stuff.html";692      await instance.loadAsset(leafPath);693      await instance.loadAsset("/stuff.js");694      await instance.loadAsset("/other.js");695      const client = new Client({696        pathMonitor: instance,697        onReload: () => {698          throw new Error("should not occur");699        }700      });701      instance.addClient(client);702      client.clientState = "active";703      instance.linkClient(client, leafPath);704      await instance.notifyClientForFsPath(path.join(servePath, "other.js"));705      expect(instance.informClients.getCalls(), "to be empty");706    });707    describe("with leafs pointing at related asset", () => {708      it("should notify any corresponding client", async () => {709        const servePath = path.join(TEST_DATA, "example-relations");710        instance = new PathMonitor({ servePath });711        const assetPath = "/stuff.js";712        await instance.loadAsset(assetPath);713        let client1Reloaded = false;714        const client1 = new Client({715          pathMonitor: instance,716          onReload: () => {717            client1Reloaded = true;718          }719        });720        const leaf1Path = "/stuff.html";721        await instance.loadAsset(leaf1Path);722        instance.addClient(client1);723        client1.clientState = "active";724        instance.linkClient(client1, leaf1Path);725        let client2Reloaded = false;726        const client2 = new Client({727          pathMonitor: instance,728          onReload: () => {729            client2Reloaded = true;730          }731        });732        const leaf2Path = "/ztuff.html";733        await instance.loadAsset(leaf2Path);734        instance.addClient(client2);735        client2.clientState = "active";736        instance.linkClient(client2, leaf2Path);737        await instance.notifyClientForFsPath(738          path.join(servePath, assetPath.slice(1))739        );740        expect(client1Reloaded, "to be true");741        expect(client2Reloaded, "to be true");742      });743    });744  });745  describe("#notifyClientForFsPathDelete", () => {746    it("should remove the asset", async () => {747      const servePath = path.join(TEST_DATA, "example-relations");748      const nodeModulesPath = toNodeModulesPath(servePath);749      const importResolver = new ImportResolver({ servePath, nodeModulesPath });750      instance = new PathMonitor({ importResolver, servePath });751      const leafPath = "/stuff.html";752      await instance.loadAsset(leafPath);753      const assetPath = "/stuff.css";754      await instance.loadAsset(assetPath);755      const client = new Client({756        pathMonitor: instance,757        onReload: () => {}758      });759      instance.addClient(client);760      client.clientState = "active";761      instance.linkClient(client, leafPath);762      await instance.notifyClientForFsPathDelete(763        path.join(servePath, assetPath.slice(1))764      );765      const cssAssets = instance.assetGraph.findAssets({766        type: "Css"767      });768      expect(cssAssets, "to be empty");769    });770    it("should notify a linked client", async () => {771      const servePath = path.join(TEST_DATA, "example-relations");772      instance = new PathMonitor({ servePath });773      const leafPath = "/stuff.html";774      await instance.loadAsset(leafPath);775      const assetPath = "/stuff.js";776      let onReloadCalled = false;777      const client = new Client({778        pathMonitor: instance,779        onReload: () => {780          onReloadCalled = true;781        }782      });783      instance.addClient(client);784      client.clientState = "active";785      instance.linkClient(client, leafPath);786      await instance.notifyClientForFsPathDelete(787        path.join(servePath, assetPath.slice(1))788      );789      expect(onReloadCalled, "to be true");790    });791    it("should ignore an orphaned related asset", async () => {792      const servePath = path.join(TEST_DATA, "example-relations");793      const nodeModulesPath = toNodeModulesPath(servePath);794      const importResolver = new ImportResolver({ servePath, nodeModulesPath });795      instance = new PathMonitor({ importResolver, servePath });796      sinon.spy(instance, "informClients");797      const leafPath = "/stuff.html";798      await instance.loadAsset(leafPath);799      await instance.loadAsset("/stuff.js");800      await instance.loadAsset("/other.js");801      const client = new Client({802        pathMonitor: instance,803        onReload: () => {804          throw new Error("should not occur");805        }806      });807      instance.addClient(client);808      client.clientState = "active";809      instance.linkClient(client, leafPath);810      await instance.notifyClientForFsPathDelete(811        path.join(servePath, "other.js")812      );813      expect(instance.informClients.getCalls(), "to be empty");814    });815    describe("when alwaysUpdateClients", () => {816      it("should send reload messages to every client", async () => {817        const servePath = path.join(TEST_DATA, "example-relations");818        const nodeModulesPath = toNodeModulesPath(servePath);819        const importResolver = new ImportResolver({820          servePath,821          nodeModulesPath822        });823        instance = new PathMonitor({824          importResolver,825          servePath,826          alwaysUpdateClients: true827        });828        const leafPath = "/stuff.html";829        await instance.loadAsset(leafPath);830        await instance.loadAsset("/stuff.js");831        await instance.loadAsset("/other.html");832        await instance.loadAsset("/other.js");833        let onReloadCalled = false;834        const client = new Client({835          pathMonitor: instance,836          onReload: () => {837            onReloadCalled = true;838          }839        });840        instance.addClient(client);841        client.clientState = "active";842        instance.linkClient(client, leafPath);843        await instance.notifyClientForFsPathDelete(844          path.join(servePath, "other.js")845        );846        expect(onReloadCalled, "to be true");847      });848      it("should remove the asset", async () => {849        const servePath = path.join(TEST_DATA, "example-relations");850        instance = new PathMonitor({ servePath });851        sinon.spy(instance, "deleteAsset");852        const leafPath = "/stuff.html";853        await instance.loadAsset(leafPath);854        const assetPath = "/stuff.js";855        await instance.loadAsset(assetPath);856        const client = new Client({857          pathMonitor: instance,858          onReload: () => {}859        });860        instance.addClient(client);861        client.clientState = "active";862        instance.linkClient(client, leafPath);863        await instance.notifyClientForFsPathDelete(864          path.join(servePath, assetPath.slice(1))865        );866        expect(instance.deleteAsset.calledOnce, "to be true");867      });868    });869  });...asset-loader-test.js
Source:asset-loader-test.js  
...150        return firstRetry;151      }152    ).catch(noop);153  });154  test('loadAsset() - throws an error if there is no loader defined for the asset type', function(assert) {155    const service = this.owner.lookup('service:asset-loader');156    const asset = { type: 'crazy-type', uri: 'someuri' };157    assert.throws(() => service.loadAsset(asset), /No loader for assets of type "crazy-type" defined./);158  });159  test('loadAsset() - returns a promise that resolves with the loaded asset information', function(assert) {160    assert.expect(1);161    const service = this.owner.lookup('service:asset-loader');162    const asset = { type: 'test', uri: 'someuri' };163    service.defineLoader('test', (uri) => RSVP.resolve(uri));164    return service.loadAsset(asset).then((result) => {165      assert.deepEqual(result, asset);166    });167  });168  test('loadAsset() - subsequent calls return the same promise', function(assert) {169    assert.expect(1);170    const service = this.owner.lookup('service:asset-loader');171    const asset = { type: 'test', uri: 'someuri' };172    service.defineLoader('test', (uri) => RSVP.resolve(uri));173    const firstCall = service.loadAsset(asset);174    const secondCall = service.loadAsset(asset);175    assert.strictEqual(firstCall, secondCall);176  });177  test('loadAsset() - rejects with an AssetLoadPromise', function(assert) {178    assert.expect(1);179    const service = this.owner.lookup('service:asset-loader');180    const asset = { type: 'test', uri: 'someuri' };181    service.defineLoader('test', () => RSVP.reject('some error'));182    return service.loadAsset(asset).then(shouldNotHappen(assert), (error) => {183      assert.equal(error.toString(), 'AssetLoadError: The test asset with uri "someuri" failed to load with the error: some error.');184    });185  });186  test('loadAsset() - a rejection allows retrying the load', function(assert) {187    assert.expect(2);188    const service = this.owner.lookup('service:asset-loader');189    const asset = { type: 'test', uri: 'someuri' };190    service.defineLoader('test', () => RSVP.reject('some error'));191    return service.loadAsset(asset).then(192      shouldNotHappen(assert),193      (error) => {194        assert.ok(true, 'first error occured');195        return error.retryLoad();196      }197    ).then(198      shouldNotHappen(assert),199      () => {200        assert.ok(true, 'retry error occured');201      }202    );203  });204  test('loadAsset() - subsequent call after rejection returns a new promise', function(assert) {205    assert.expect(2);206    const service = this.owner.lookup('service:asset-loader');207    const asset = { type: 'test', uri: 'someuri' };208    let firstRetry;209    service.defineLoader('test', () => RSVP.reject('some error'));210    return service.loadAsset(asset).then(211      shouldNotHappen(assert),212      (error) => firstRetry = error.retryLoad()213    ).then(214      shouldNotHappen(assert),215      () => {216        service.defineLoader('test', () => RSVP.resolve());217        const serviceRetry = service.loadAsset(asset);218        assert.notStrictEqual(firstRetry, serviceRetry, 'calling loadAsset again returns other result');219        return serviceRetry;220      }221    ).then(shouldHappen(assert), shouldNotHappen(assert));222  });223  test('loadAsset() - retrying a load twice returns the same promise', function(assert) {224    assert.expect(2);225    const service = this.owner.lookup('service:asset-loader');226    const asset = { type: 'test', uri: 'someuri' };227    service.defineLoader('test', () => RSVP.reject('some error'));228    return service.loadAsset(asset).then(229      shouldNotHappen(assert),230      (error) => {231        const firstRetry = error.retryLoad();232        const secondRetry = error.retryLoad();233        const serviceRetry = service.loadAsset(asset);234        assert.strictEqual(firstRetry, secondRetry, 'multiple retries produce same results');235        assert.strictEqual(firstRetry, serviceRetry, 'calling loadBundle again returns the retry result');236        return firstRetry;237      }238    ).catch(noop);239  });240  test('loadAsset() - js - handles successful load', function(assert) {241    assert.expect(1);242    const service = this.owner.lookup('service:asset-loader');243    const asset = { type: 'js', uri: '/unit-test.js' };244    return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert));245  });246  test('loadAsset() - js - handles failed load', function(assert) {247    assert.expect(1);248    const service = this.owner.lookup('service:asset-loader');249    const asset = { type: 'js', uri: '/unit-test.jsss' };250    return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert));251  });252  test('loadAsset() - js - does not insert additional script tag if asset is in DOM already', function(assert) {253    assert.expect(1);254    if (!document.querySelector('script[src="/unit-test.js"]')) {255      const script = document.createElement('script');256      script.src = '/unit-test.js';257      document.body.appendChild(script);258    }259    const service = this.owner.lookup('service:asset-loader');260    const asset = { type: 'js', uri: '/unit-test.js' };261    const numScripts = document.querySelectorAll('script').length;262    return service.loadAsset(asset).then(() => {263      const newNumScripts = document.querySelectorAll('script').length;264      assert.equal(newNumScripts, numScripts);265    });266  });267  test('loadAsset() - js - sets async false to try to guarantee execution order', function(assert) {268    assert.expect(1);269    const service = this.owner.lookup('service:asset-loader');270    const asset = { type: 'js', uri: '/unit-test.js' };271    return service.loadAsset(asset).then(() => {272      const script = document.querySelector('script[src="/unit-test.js"]');273      assert.equal(script.async, false);274    });275  });276  test('loadAsset() - css - handles successful load', function(assert) {277    assert.expect(1);278    const service = this.owner.lookup('service:asset-loader');279    const asset = { type: 'css', uri: '/unit-test.css' };280    return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert));281  });282  test('loadAsset() - css - handles failed load', function(assert) {283    assert.expect(1);284    const service = this.owner.lookup('service:asset-loader');285    const asset = { type: 'css', uri: '/unit-test.csss' };286    // Since onload/onerror support is spotty for link elements, we allow287    // non-Chrome browsers to either resolve or reject (they should do something).288    var isChrome = !!window.chrome && window.navigator.vendor === 'Google Inc.';289    if (isChrome) {290      return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert));291    } else {292      return service.loadAsset(asset).then(shouldHappen(assert), shouldHappen(assert));293    }294  });295  test('loadAsset() - css - does not insert additional link tag if asset is in DOM already', function(assert) {296    assert.expect(1);297    if (!document.querySelector('link[href="/unit-test.css"]')) {298      const link = document.createElement('link');299      link.href = '/unit-test.css';300      document.head.appendChild(link);301    }302    const service = this.owner.lookup('service:asset-loader');303    const asset = { type: 'css', uri: '/unit-test.css' };304    const numLinks = document.querySelectorAll('link').length;305    return service.loadAsset(asset).then(() => {306      const newNumLinks = document.querySelectorAll('link').length;307      assert.equal(newNumLinks, numLinks);308    });309  });310  test('defineLoader() - overwrites existing asset loader types', function(assert) {311    assert.expect(1);312    const service = this.owner.lookup('service:asset-loader');313    const asset = { type: 'test', uri: 'someuri' };314    service.defineLoader('test', () => RSVP.reject());315    service.defineLoader('test', () => RSVP.resolve());316    return service.loadAsset(asset).then(317      () => assert.ok(true),318      shouldNotHappen(assert)319    );320  });321  test('pushManifest() - throws an error when merging two manifests with the same bundle', function(assert) {322    const service = this.owner.lookup('service:asset-loader');323    const manifest = {324      bundles: {325        blog: {}326      }327    };328    service.pushManifest(manifest);329    assert.throws(() => service.pushManifest(manifest), /The bundle "blog" already exists./);330  });...seed.js
Source:seed.js  
...34];35const productSeedStrabucks = [36  {37    product_name: "Caffè Americano",38    product_imgUrl: loadAsset("/Drink/Coffee/image.png"), //img from Sung39    threeD_imgUrl: "", //img with mtl and obj40    price: 499,41    description:42      "Espresso shots topped with hot water create a light layer of crema culminating in this wonderfully rich cup with depth and nuance.",43    product_type: "Drink",44    assets: {45      name: "coffee cup",46      source: loadAsset(`/Drink/Coffee/coffee_cup_obj.obj`),47      mtl: loadAsset(`/Drink/Coffee/coffee_cup_obj.mtl`),48      type: "OBJ",49      scale: 0.2,50      rotate: 0,51    },52  },53  {54    product_name: "Pie",55    product_imgUrl: loadAsset("/Dessert/Pie/pie.png"), //img from Sung56    threeD_imgUrl: "", //img with mtl and obj57    price: 1399,58    description:59      "Filled with the perfect blend of locally grown Granny Smith and Cortland apples, seasoned with a hint of cinnamon and sugar and topped with our original buttery flaky pie crust.",60    product_type: "Dessert",61    assets: {62      name: "pie",63      source: loadAsset(`/Dessert/Pie/11547_Dessert_pie_v3_l2.obj`),64      mtl: loadAsset(`/Dessert/Pie/11547_Dessert_pie_v3_l2.mtl`),65      type: "OBJ",66      scale: 0.01,67      rotate: -90,68    },69  },70  {71    product_name: "Pizza",72    product_imgUrl: loadAsset("/Entree/Pizza/pizzaslice.png"), //img from Sung73    threeD_imgUrl: "", //img with mtl and obj74    price: 499,75    description:76      "Thin-crust oven baked pizza topped with spicy pepperon, mozzarella, and homemade tomato sauce.",77    product_type: "Entree",78    assets: {79      name: "pizza",80      source: loadAsset(`/Entree/Pizza/Pizza.obj`),81      mtl: loadAsset(`/Entree/Pizza/Pizza.mtl`),82      type: "OBJ",83      scale: 0.01,84      rotate: -90,85    },86  },87  {88    product_name: "Bread",89    product_imgUrl: loadAsset("/HighPolyFood/Bread/005.png"), //img from Sung90    threeD_imgUrl: "", //img with mtl and obj91    price: 1999,92    description: "Locally Made White & Pumpernickel Baguettes",93    product_type: "Appetizer",94    assets: {95      name: "bread",96      source: loadAsset(`/HighPolyFood/Bread/005.obj`),97      mtl: loadAsset(`/HighPolyFood/Bread/005.mtl`),98      type: "OBJ",99      scale: 0.01,100      rotate: 0,101    },102  },103  {104    product_name: "Burrito",105    product_imgUrl: loadAsset("/HighPolyFood/Burrito/042.png"), //img from Sung106    threeD_imgUrl: "", //img with mtl and obj107    price: 1999,108    description:109      "A burrito suizo means a burrito with melted cheese or a cheese sauce on top. âSuizoâ means Swiss in Spanish (as in Swiss cheese), but the term is used to refer to any type of cheese.",110    product_type: "Entree",111    assets: {112      name: "burrito",113      source: loadAsset(`/HighPolyFood/Burrito/042.obj`),114      mtl: loadAsset(`/HighPolyFood/Burrito/042.mtl`),115      type: "OBJ",116      scale: 0.01,117      rotate: 0,118    },119  },120  {121    product_name: "Pretzel",122    product_imgUrl: loadAsset("/Appetizer/Pretzel/pretzel.png"), //img from Sung123    threeD_imgUrl: "", //img with mtl and obj124    price: 499,125    description:126      "Mall pretzels that you can now enjoy in the comfort of your home for a fraction of the price with countless dipping sauce option! They are the perfect party food or snack to impress guests with and they really are easier to make than youâd think.",127    product_type: "Appetizer",128    assets: {129      name: "pretzel",130      source: loadAsset(131        `/Appetizer/Pretzel/13933_Big_Pretzel_on_Napkin_v3_l2.obj`132      ),133      mtl: loadAsset(134        `/Appetizer/Pretzel/13933_Big_Pretzel_on_Napkin_v3_l2.mtl`135      ),136      type: "OBJ",137      scale: 0.01,138      rotate: -90,139    },140  },141  {142    product_name: "Coca Cola",143    product_imgUrl: loadAsset("/Drink/Soda/cokecan.png"), //img from Sung144    threeD_imgUrl: "", //img with mtl and obj145    price: 199,146    description: "Fizzy, cold, delicious",147    product_type: "Drink",148    assets: {149      name: "cocacola",150      source: loadAsset(`/Drink/Soda/14025_Soda_Can_v3_l3.obj`),151      mtl: loadAsset(`/Drink/Soda/14025_Soda_Can_v3_l3.mtl`),152      type: "OBJ",153      scale: 0.01,154      rotate: -90,155    },156  },157  {158    product_name: "Reuben",159    product_imgUrl: loadAsset("/Entree/Reuben/rubensandwich.png"), //img from Sung160    threeD_imgUrl: "", //img with mtl and obj161    price: 699,162    description:163      "With layers of mouthwatering meat, yummy fillings (of your choice), and crunchy vegetables, Arbyâs reuben sandwich is truly an iconic dish! Who can say no to a sandwich stuffed with flavorful sauces, melted cheese, and luscious meat fillings? ",164    product_type: "Entree",165    assets: {166      name: "reuben",167      source: loadAsset(168        `/Entree/Reuben/13931_Reuben_Sandwich_on_Plate_v2_L1.obj`169      ),170      mtl: loadAsset(`/Entree/Reuben/13931_Reuben_Sandwich_on_Plate_v2_L1.mtl`),171      type: "OBJ",172      scale: 0.01,173      rotate: -90,174    },175  },176];177const productSeed = [178  ...productSeedStrabucks,179  ...productSeedStrabucks,180  {181    product_name: "Cupcake",182    product_imgUrl: loadAsset("/Dessert/Cupcake/cupcake.png"), //img from Sung183    threeD_imgUrl: "", //img with mtl and obj184    price: 199,185    description:186      "Colorful, moist, delicious cupcakes, with extra frosting. Yummy mmm good",187    product_type: "Dessert",188    assets: {189      name: "cupcake",190      source: loadAsset(`/Dessert/Cupcake/12187_Cupcake_v1_L3.obj`),191      mtl: loadAsset(`/Dessert/Cupcake/12187_Cupcake_v1_L3.mtl`),192      type: "OBJ",193      scale: 0.01,194      rotate: -90,195    },196  },197  {198    product_name: "Birthday Cake",199    product_imgUrl: loadAsset("/Dessert/BirthdayCake/cake.png"), //img from Sung200    threeD_imgUrl: "", //img with mtl and obj201    price: 1299,202    description:203      "This quadruple-layer cake isn't nearly as fussy to make as you might think. It starts out as a standard two-layer cake, then each layer is cut in half and stacked, with an easy filling in between the layers. The result is a moist cake that keeps well without refrigeration; looks spectacular when cut, and tastes even better than it looks!",204    product_type: "Dessert",205    assets: {206      name: "birthdaycake",207      source: loadAsset(`/Dessert/BirthdayCake/10868_birthday-cake_v3.obj`),208      mtl: loadAsset(`/Dessert/BirthdayCake/10868_birthday-cake_v3.mtl`),209      type: "OBJ",210      scale: 0.01,211      rotate: -90,212    },213  },214  {215    product_name: "Cabernet Sauvignon",216    product_imgUrl: loadAsset("/Drink/Wine/wine.png"), //img from Sung217    threeD_imgUrl: "", //img with mtl and obj218    price: 1099,219    description:220      "Woodbridge by Robert Mondavi Cabernet Sauvignon Red Wine is a medium-bodied California wine that opens with enticing aromas of cherries, berries, rich cedar, brown sugar, and toast.",221    product_type: "Drink",222    assets: {223      name: "red wine",224      source: loadAsset(`/Drink/Wine/14042_750_mL_Wine_Bottle_r_v1_L3.obj`),225      mtl: loadAsset(`/Drink/Wine/14042_750_mL_Wine_Bottle_r_v1_L3.mtl`),226      type: "OBJ",227      scale: 0.01,228      rotate: -90,229    },230  },231  {232    product_name: "Pizza",233    product_imgUrl: loadAsset("/HighPolyFood/Pizza/035.png"), //img from Sung234    threeD_imgUrl: "", //img with mtl and obj235    price: 1999,236    description:237      "San Marzano tomato sauce, fresh mozzarella fior di latte, fresh organic basil",238    product_type: "Entree",239    assets: {240      name: "pizza",241      source: loadAsset(`/HighPolyFood/Pizza/035.obj`),242      mtl: loadAsset(`/HighPolyFood/Pizza/035.mtl`),243      type: "OBJ",244      scale: 0.01,245      rotate: 0,246    },247  },248  {249    product_name: "Ribs",250    product_imgUrl: loadAsset("/HighPolyFood/Ribs/049.png"), //img from Sung251    threeD_imgUrl: "", //img with mtl and obj252    price: 1999,253    description: "Yummy mmm good",254    product_type: "Entree",255    assets: {256      name: "ribs",257      source: loadAsset(`/HighPolyFood/Ribs/049.obj`),258      mtl: loadAsset(`/HighPolyFood/Ribs/049.mtl`),259      type: "OBJ",260      scale: 0.01,261      rotate: 0,262    },263  },264  {265    product_name: "Steak",266    product_imgUrl: loadAsset("/HighPolyFood/Steak/050.png"), //img from Sung267    threeD_imgUrl: "", //img with mtl and obj268    price: 1999,269    description: "New York Steak / Bell Peppers / Spice Blend. Yummy mmm good",270    product_type: "Entree",271    assets: {272      name: "steak",273      source: loadAsset(`/HighPolyFood/Steak/050.obj`),274      mtl: loadAsset(`/HighPolyFood/Steak/050.mtl`),275      type: "OBJ",276      scale: 0.01,277      rotate: 0,278    },279  },280];281const restaurantSeed = [282  {283    name: "Starbucks",284    imgUrl: "RestaurantLogos/starbucks.jpeg",285  },286  {287    name: "Shake Shack",288    imgUrl: "RestaurantLogos/shakeshack-logo.png",...ImageUrl.js
Source:ImageUrl.js  
...34    var source = new ImageUrlSource.fromString(35        "http://localhost/img?f={f}&z={z}&x={x}&y={y}");36    var spy = sinon.stub().returns(function() {});37    var stage = { loadImage: spy };38    source.loadAsset(stage, { face: "l", z: 0, x: 1, y: 2});39    source.loadAsset(stage, { face: "r", z: 3, x: 4, y: 5});40    wait.until(function() { return spy.callCount === 2; }, function() {41      assert.strictEqual(spy.getCall(0).args[0], "http://localhost/img?f=l&z=0&x=1&y=2");42      assert.strictEqual(spy.getCall(0).args[1], undefined);43      assert.strictEqual(spy.getCall(1).args[0], "http://localhost/img?f=r&z=3&x=4&y=5");44      assert.strictEqual(spy.getCall(1).args[1], undefined);45      done();46    });47  });48  test('template url with preview', function(done) {49    var defaultOrder = "bdflru";50    var source = new ImageUrlSource.fromString(51        "http://localhost/img?f={f}&z={z}&x={x}&y={y}",52        {cubeMapPreviewUrl: "http://localhost/preview", concurrency: 10});53    var spy = sinon.stub().returns(function() {});54    var stage = { loadImage: spy };55    for (var i = 0; i < 6; i++) {56      source.loadAsset(stage, { face: defaultOrder[i], z: 0, x: 0, y: 0});57    }58    source.loadAsset(stage, { face: "l", z: 1, x: 2, y: 3});59    wait.until(function() { return stage.loadImage.callCount === 7; }, function() {60      for (var i = 0; i < 6; i++) {61        assert.strictEqual(spy.getCall(i).args[0], "http://localhost/preview");62        assert.deepEqual(spy.getCall(i).args[1], {x: 0, y: i/6, width: 1, height: 1/6});63      }64      assert.strictEqual(spy.getCall(6).args[0], "http://localhost/img?f=l&z=1&x=2&y=3");65      assert.strictEqual(spy.getCall(6).args[1], undefined);66      done();67    });68  });69  test('template url with preview in custom order', function(done) {70    var customOrder = "udtblr";71    var source = new ImageUrlSource.fromString(72        "http://localhost/img?f={f}&z={z}&x={x}&y={y}",73        {cubeMapPreviewUrl: "http://localhost/preview", cubeMapPreviewFaceOrder: customOrder, concurrency: 10});74    var spy = sinon.stub().returns(function() {});75    var stage = { loadImage: spy };76    for (var i = 0; i < 6; i++) {77      source.loadAsset(stage, { face: customOrder[i], z: 0, x: 0, y: 0});78    }79    source.loadAsset(stage, { face: "l", z: 1, x: 2, y: 3});80    wait.until(function() { return stage.loadImage.callCount === 7; }, function() {81      for (var i = 0; i < 6; i++) {82        assert.strictEqual(spy.getCall(i).args[0], "http://localhost/preview");83        assert.deepEqual(spy.getCall(i).args[1], {x: 0, y: i/6, width: 1, height: 1/6});84      }85      assert.strictEqual(spy.getCall(6).args[0], "http://localhost/img?f=l&z=1&x=2&y=3");86      assert.strictEqual(spy.getCall(6).args[1], undefined);87      done();88    });89  });90  test('full rect', function(done) {91    var stage = new MockStage();92    var tileToUrl = sinon.stub().withArgs("tile").returns({ url: "url" });93    var source = new ImageUrlSource(tileToUrl);94    source.loadAsset(stage, "tile", function(err, tile, asset) {95      assert.isNull(err);96      assert.strictEqual("tile", tile);97      assert.strictEqual("asset", asset);98      done();99    });100  });101  test('partial rect', function(done) {102    var stage = new MockStage();103    var tileToUrl = sinon.stub().withArgs("tile").returns({ url: "url-rect", rect: "rect" });104    var source = new ImageUrlSource(tileToUrl);105    source.loadAsset(stage, "tile", function(err, tile, asset) {106      assert.isNull(err);107      assert.strictEqual(tile, "tile");108      assert.strictEqual(asset, "asset-rect");109      done();110    });111  });112  test('error', function(done) {113    var stage = new MockStage();114    var tileToUrl = sinon.stub().withArgs("tile").returns({ url: "url-error" });115    var source = new ImageUrlSource(tileToUrl);116    source.loadAsset(stage, "tile", function(err, tile, asset) {117      assert.instanceOf(err, Error);118      assert.strictEqual(tile, "tile");119      assert.isNotOk(asset);120      done();121    });122  });123  // TODO: Test retry ratelimiting....dev.js
Source:dev.js  
...23});24//ASSET LOAD TEST25/* load an asset into the engine */26let sampleAsset = require("../sampleData/cuelist.json");27let sha1 = engine.loadAsset(sampleAsset);28let sha2 = engine.loadAsset(sampleAsset);29let sha3 = engine.loadAsset(sampleAsset);30let sha4 = engine.loadAsset(sampleAsset);31let sha5 = engine.loadAsset(sampleAsset);32let sha6 = engine.loadAsset(sampleAsset);33let sha7 = engine.loadAsset(sampleAsset);34let sha8 = engine.loadAsset(sampleAsset);35let sha9 = engine.loadAsset(sampleAsset);36let sha0 = engine.loadAsset(sampleAsset);37let sha20 = engine.loadAsset(sampleAsset);38let sha21 = engine.loadAsset(sampleAsset);39let sha22 = engine.loadAsset(sampleAsset);40let sha23 = engine.loadAsset(sampleAsset);41let sha24 = engine.loadAsset(sampleAsset);42let sha25 = engine.loadAsset(sampleAsset);43let sha26 = engine.loadAsset(sampleAsset);44let sha27 = engine.loadAsset(sampleAsset);45let sha28 = engine.loadAsset(sampleAsset);46let sha29 = engine.loadAsset(sampleAsset);47let sha30 = engine.loadAsset(sampleAsset);48let sha31 = engine.loadAsset(sampleAsset);49let sha32 = engine.loadAsset(sampleAsset);50let sha33 = engine.loadAsset(sampleAsset);51let sha34 = engine.loadAsset(sampleAsset);52let sha35 = engine.loadAsset(sampleAsset);53let sha36 = engine.loadAsset(sampleAsset);54let sha37 = engine.loadAsset(sampleAsset);55let sha38 = engine.loadAsset(sampleAsset);56let sha39 = engine.loadAsset(sampleAsset);57let sha40 = engine.loadAsset(sampleAsset);58let sha41 = engine.loadAsset(sampleAsset);59let sha42 = engine.loadAsset(sampleAsset);60let sha43 = engine.loadAsset(sampleAsset);61let sha44 = engine.loadAsset(sampleAsset);62let sha45 = engine.loadAsset(sampleAsset);63let sha46 = engine.loadAsset(sampleAsset);64let sha47 = engine.loadAsset(sampleAsset);65let sha48 = engine.loadAsset(sampleAsset);66let sha49 = engine.loadAsset(sampleAsset);67let sha50 = engine.loadAsset(sampleAsset);68let sha51 = engine.loadAsset(sampleAsset);69let sha52 = engine.loadAsset(sampleAsset);70let sha53 = engine.loadAsset(sampleAsset);71let sha54 = engine.loadAsset(sampleAsset);72let sha55 = engine.loadAsset(sampleAsset);73let sha56 = engine.loadAsset(sampleAsset);74let sha57 = engine.loadAsset(sampleAsset);75let sha58 = engine.loadAsset(sampleAsset);76let sha59 = engine.loadAsset(sampleAsset);77//ASSET PLAY TEST78engine.play(sha1);79engine.play(sha2);80engine.play(sha3);81engine.play(sha4);82engine.play(sha5);83engine.play(sha6);84engine.play(sha7);85engine.play(sha8);86engine.play(sha9);87engine.play(sha0);88engine.play(sha20);89engine.play(sha21);90engine.play(sha22);...heavy-assets.js
Source:heavy-assets.js  
...8});9//ASSET LOAD TEST10/* load an asset into the engine */11let sampleAsset = require("../sampleData/cuelist.json");12let sha1 = engine.loadAsset(sampleAsset);13let sha2 = engine.loadAsset(sampleAsset);14let sha3 = engine.loadAsset(sampleAsset);15let sha4 = engine.loadAsset(sampleAsset);16let sha5 = engine.loadAsset(sampleAsset);17let sha6 = engine.loadAsset(sampleAsset);18let sha7 = engine.loadAsset(sampleAsset);19let sha8 = engine.loadAsset(sampleAsset);20let sha9 = engine.loadAsset(sampleAsset);21let sha0 = engine.loadAsset(sampleAsset);22let sha20 = engine.loadAsset(sampleAsset);23let sha21 = engine.loadAsset(sampleAsset);24let sha22 = engine.loadAsset(sampleAsset);25let sha23 = engine.loadAsset(sampleAsset);26let sha24 = engine.loadAsset(sampleAsset);27let sha25 = engine.loadAsset(sampleAsset);28let sha26 = engine.loadAsset(sampleAsset);29let sha27 = engine.loadAsset(sampleAsset);30let sha28 = engine.loadAsset(sampleAsset);31let sha29 = engine.loadAsset(sampleAsset);32let sha30 = engine.loadAsset(sampleAsset);33let sha31 = engine.loadAsset(sampleAsset);34let sha32 = engine.loadAsset(sampleAsset);35let sha33 = engine.loadAsset(sampleAsset);36let sha34 = engine.loadAsset(sampleAsset);37let sha35 = engine.loadAsset(sampleAsset);38let sha36 = engine.loadAsset(sampleAsset);39let sha37 = engine.loadAsset(sampleAsset);40let sha38 = engine.loadAsset(sampleAsset);41let sha39 = engine.loadAsset(sampleAsset);42let sha40 = engine.loadAsset(sampleAsset);43let sha41 = engine.loadAsset(sampleAsset);44let sha42 = engine.loadAsset(sampleAsset);45let sha43 = engine.loadAsset(sampleAsset);46let sha44 = engine.loadAsset(sampleAsset);47let sha45 = engine.loadAsset(sampleAsset);48let sha46 = engine.loadAsset(sampleAsset);49let sha47 = engine.loadAsset(sampleAsset);50let sha48 = engine.loadAsset(sampleAsset);51let sha49 = engine.loadAsset(sampleAsset);52let sha50 = engine.loadAsset(sampleAsset);53let sha51 = engine.loadAsset(sampleAsset);54let sha52 = engine.loadAsset(sampleAsset);55let sha53 = engine.loadAsset(sampleAsset);56let sha54 = engine.loadAsset(sampleAsset);57let sha55 = engine.loadAsset(sampleAsset);58let sha56 = engine.loadAsset(sampleAsset);59let sha57 = engine.loadAsset(sampleAsset);60let sha58 = engine.loadAsset(sampleAsset);61let sha59 = engine.loadAsset(sampleAsset);62//ASSET PLAY TEST63engine.play(sha1);64engine.play(sha2);65engine.play(sha3);66engine.play(sha4);67engine.play(sha5);68engine.play(sha6);69engine.play(sha7);70engine.play(sha8);71engine.play(sha9);72engine.play(sha0);73engine.play(sha20);74engine.play(sha21);75engine.play(sha22);...load-assets.js
Source:load-assets.js  
...7}8export default function (developmentMode) {9    const scriptNameSuffix = developmentMode ? 'js' : 'min.js';10    return {11        favIcon:      loadAsset('./client/ui/favicon.ico', true),12        coreScript:   loadAsset(`./client/core/index.${scriptNameSuffix}`),13        driverScript: loadAsset(`./client/driver/index.${scriptNameSuffix}`),14        uiScript:     loadAsset(`./client/ui/index.${scriptNameSuffix}`),15        uiStyle:      loadAsset('./client/ui/styles.css'),16        uiSprite:     loadAsset('./client/ui/sprite.png', true),17        uiSpriteSvg:  loadAsset('./client/ui/sprite.svg', true),18        idlePageScript: loadAsset('./client/browser/idle-page/index.js'),19        idlePageStyle:  loadAsset('./client/browser/idle-page/styles.css'),20        idlePageLogo:   loadAsset('./client/browser/idle-page/logo.svg', true),21        serviceWorkerScript: loadAsset('./client/browser/service-worker.js'),22        automationScript: loadAsset(`./client/automation/index.${scriptNameSuffix}`),23        // NOTE: Load the legacy client script lazily to reduce startup time24        legacyRunnerScript: require('testcafe-legacy-api').CLIENT_RUNNER_SCRIPT,25    };...assets.js
Source:assets.js  
1const fs = require('fs');2const path = require('path');3const { toBitmap } = require('./bitmap');4function loadAsset(name) {5  const assetFile = path.join(__dirname, '../assets', name + '.txt')6  const bitmapData = fs.readFileSync(assetFile).toString();7  return new Uint8Array(toBitmap(bitmapData).bitmap);8}9module.exports = {10  0: loadAsset('0'),11  1: loadAsset('1'),12  2: loadAsset('2'),13  3: loadAsset('3'),14  4: loadAsset('4'),15  5: loadAsset('5'),16  6: loadAsset('6'),17  7: loadAsset('7'),18  8: loadAsset('8'),19  9: loadAsset('9'),20  A: loadAsset('A'),21  colon: loadAsset('colon'),22  E: loadAsset('E'),23  G: loadAsset('G'),24  H: loadAsset('H'),25  I: loadAsset('I'),26  M: loadAsset('M'),27  O: loadAsset('O'),28  R: loadAsset('R'),29  trex: loadAsset('trex'),30  V: loadAsset('V'),31  s0: loadAsset('small/0'),32  s1: loadAsset('small/1'),33  s2: loadAsset('small/2'),34  s3: loadAsset('small/3'),35  s4: loadAsset('small/4'),36  s5: loadAsset('small/5'),37  s6: loadAsset('small/6'),38  s7: loadAsset('small/7'),39  s8: loadAsset('small/8'),40  s9: loadAsset('small/9')...Using AI Code Generation
1import { Selector } from 'testcafe';2test('My first test', async t => {3        .typeText('#developer-name', 'John Smith')4        .click('#submit-button')5        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');6});7import { Selector } from 'testcafe';8test('My first test', async t => {9        .typeText('#developer-name', 'John Smith')10        .click('#submit-button')11        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');12});13import { Selector } from 'testcafe';14test('My first test', async t => {15        .typeText('#developer-name', 'John Smith')16        .click('#submit-button')17        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');18});19import { Selector } from 'testcafe';20test('My first test', async t => {21        .typeText('#developer-name', 'John Smith')22        .click('#submit-button')23        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');24});25import { Selector } from 'testcafe';26test('My first test', async tUsing AI Code Generation
1import { Selector } from 'testcafe';2test('My Test', async t => {3    const uploadInput = Selector('#file-upload');4    await t.setFilesToUpload(uploadInput, './test.js');5});6import { Selector } from 'testcafe';7test('My Test', async t => {8    const uploadInput = Selector('#file-upload');9    await t.setFilesToUpload(uploadInput, './test.js');10});Using AI Code Generation
1import { loadAsset } from 'testcafe-browser-provider-electron';2test('My Test', async t => {3    await loadAsset('test.js');4    await t.click('#button');5});6import { loadAsset } from 'testcafe-browser-provider-electron';7test('My Test', async t => {8    await loadAsset('test.js');9    await t.click('#button');10});Using AI Code Generation
1import { loadAsset } from 'testcafe-browser-provider-electron';2    .beforeEach(async t => {3        await t.maximizeWindow();4        await t.wait(1000);5    });6test('test', async t => {7    await t.click('#test');8});9const createTestCafe = require('testcafe');10const electron = require('testcafe-browser-provider-electron');11const testCafe = await createTestCafe('localhost', 1337, 1338);12const runner = testCafe.createRunner();13    .src(['test.js'])14    .browsers('electron:headless')15    .run();16await testCafe.close();Using AI Code Generation
1import { ClientFunction } from 'testcafe';2import { Selector } from 'testcafe';3import { loadAsset } from './utils';4test('My first test', async t => {5        .expect(Selector('#developer-name').value).eql('', 'input is empty')6        .typeText('#developer-name', 'John Smith')7        .click('#submit-button')8        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!', 'header is updated');9});10import { RequestLogger } from 'testcafe';11export const loadAsset = async (t, url, options) => {12    const logger = RequestLogger(url, options);13    await t.addRequestHooks(logger);14    await t.eval(() => window.fetch(arguments[0], arguments[1]), { dependencies: { url, options } });15    await logger.contains(record => record.response.statusCode === 200);16};17import { ClientFunction } from 'testcafe';18import { Selector } from 'testcafe';19import { loadAsset } from './utils';20test('My first test', async t => {21        .expect(Selector('#developer-name').value).eql('', 'input is empty')22        .typeText('#developer-name', 'John Smith')23        .click('#submit-button')24        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!', 'header is updated');25});Using AI Code Generation
1var path = require('path');2var fileName = 'file.txt';3var filePath = path.join(__dirname, fileName);4var uploadButton = Selector('input[type="file"]');5    .setFilesToUpload(uploadButton, filePath);6var uploadButton = Selector('input[type="file"]');7    .setFilesToUpload(uploadButton, 'file.txt');Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
