How to use root method in Cypress

Best JavaScript code snippet using cypress

storeStressTestConcurrent-test.js

Source:storeStressTestConcurrent-test.js Github

copy

Full Screen

1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9describe('StoreStressConcurrent', () => {10  let React;11  let ReactDOM;12  let act;13  let actAsync;14  let bridge;15  let store;16  let print;17  beforeEach(() => {18    bridge = global.bridge;19    store = global.store;20    store.collapseNodesByDefault = false;21    React = require('react');22    ReactDOM = require('react-dom');23    act = require('./utils').act;24    // TODO: Figure out recommendation for concurrent mode tests, then replace25    // this helper with the real thing.26    actAsync = require('./utils').actAsync;27    print = require('./storeSerializer').print;28  });29  // TODO: Remove this in favor of @gate pragma30  if (!__EXPERIMENTAL__) {31    it("empty test so Jest doesn't complain", () => {});32    return;33  }34  // This is a stress test for the tree mount/update/unmount traversal.35  // It renders different trees that should produce the same output.36  it('should handle a stress test with different tree operations (Concurrent Mode)', () => {37    let setShowX;38    const A = () => 'a';39    const B = () => 'b';40    const C = () => {41      // We'll be manually flipping this component back and forth in the test.42      // We only do this for a single node in order to verify that DevTools43      // can handle a subtree switching alternates while other subtrees are memoized.44      const [showX, _setShowX] = React.useState(false);45      setShowX = _setShowX;46      return showX ? <X /> : 'c';47    };48    const D = () => 'd';49    const E = () => 'e';50    const X = () => 'x';51    const a = <A key="a" />;52    const b = <B key="b" />;53    const c = <C key="c" />;54    const d = <D key="d" />;55    const e = <E key="e" />;56    function Parent({children}) {57      return children;58    }59    // 1. Render a normal version of [a, b, c, d, e].60    let container = document.createElement('div');61    // $FlowFixMe62    let root = ReactDOM.createRoot(container);63    act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));64    expect(store).toMatchInlineSnapshot(65      `66      [root]67        ▾ <Parent>68            <A key="a">69            <B key="b">70            <C key="c">71            <D key="d">72            <E key="e">73    `,74    );75    expect(container.textContent).toMatch('abcde');76    const snapshotForABCDE = print(store);77    // 2. Render a version where <C /> renders an <X /> child instead of 'c'.78    // This is how we'll test an update to a single component.79    act(() => {80      setShowX(true);81    });82    expect(store).toMatchInlineSnapshot(83      `84      [root]85        ▾ <Parent>86            <A key="a">87            <B key="b">88          ▾ <C key="c">89              <X>90            <D key="d">91            <E key="e">92    `,93    );94    expect(container.textContent).toMatch('abxde');95    const snapshotForABXDE = print(store);96    // 3. Verify flipping it back produces the original result.97    act(() => {98      setShowX(false);99    });100    expect(container.textContent).toMatch('abcde');101    expect(print(store)).toBe(snapshotForABCDE);102    // 4. Clean up.103    act(() => root.unmount());104    expect(print(store)).toBe('');105    // Now comes the interesting part.106    // All of these cases are equivalent to [a, b, c, d, e] in output.107    // We'll verify that DevTools produces the same snapshots for them.108    // These cases are picked so that rendering them sequentially in the same109    // container results in a combination of mounts, updates, unmounts, and reorders.110    // prettier-ignore111    const cases = [112      [a, b, c, d, e],113      [[a], b, c, d, e],114      [[a, b], c, d, e],115      [[a, b], c, [d, e]],116      [[a, b], c, [d, '', e]],117      [[a], b, c, d, [e]],118      [a, b, [[c]], d, e],119      [[a, ''], [b], [c], [d], [e]],120      [a, b, [c, [d, ['', e]]]],121      [a, b, c, d, e],122      [<div key="0">{a}</div>, b, c, d, e],123      [<div key="0">{a}{b}</div>, c, d, e],124      [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],125      [<div key="1">{a}{b}</div>, c, <div key="0">{d}{e}</div>],126      [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],127      [<div key="2">{a}{b}</div>, c, <div key="3">{d}{e}</div>],128      [<span key="0">{a}</span>, b, c, d, [e]],129      [a, b, <span key="0"><span>{c}</span></span>, d, e],130      [<div key="0">{a}</div>, [b], <span key="1">{c}</span>, [d], <div key="2">{e}</div>],131      [a, b, [c, <div key="0">{d}<span>{e}</span></div>], ''],132      [a, [[]], b, c, [d, [[]], e]],133      [[[a, b, c, d], e]],134      [a, b, c, d, e],135    ];136    // 5. Test fresh mount for each case.137    for (let i = 0; i < cases.length; i++) {138      // Ensure fresh mount.139      container = document.createElement('div');140      // $FlowFixMe141      root = ReactDOM.createRoot(container);142      // Verify mounting 'abcde'.143      act(() => root.render(<Parent>{cases[i]}</Parent>));144      expect(container.textContent).toMatch('abcde');145      expect(print(store)).toEqual(snapshotForABCDE);146      // Verify switching to 'abxde'.147      act(() => {148        setShowX(true);149      });150      expect(container.textContent).toMatch('abxde');151      expect(print(store)).toBe(snapshotForABXDE);152      // Verify switching back to 'abcde'.153      act(() => {154        setShowX(false);155      });156      expect(container.textContent).toMatch('abcde');157      expect(print(store)).toBe(snapshotForABCDE);158      // Clean up.159      act(() => root.unmount());160      expect(print(store)).toBe('');161    }162    // 6. Verify *updates* by reusing the container between iterations.163    // There'll be no unmounting until the very end.164    container = document.createElement('div');165    // $FlowFixMe166    root = ReactDOM.createRoot(container);167    for (let i = 0; i < cases.length; i++) {168      // Verify mounting 'abcde'.169      act(() => root.render(<Parent>{cases[i]}</Parent>));170      expect(container.textContent).toMatch('abcde');171      expect(print(store)).toEqual(snapshotForABCDE);172      // Verify switching to 'abxde'.173      act(() => {174        setShowX(true);175      });176      expect(container.textContent).toMatch('abxde');177      expect(print(store)).toBe(snapshotForABXDE);178      // Verify switching back to 'abcde'.179      act(() => {180        setShowX(false);181      });182      expect(container.textContent).toMatch('abcde');183      expect(print(store)).toBe(snapshotForABCDE);184      // Don't unmount. Reuse the container between iterations.185    }186    act(() => root.unmount());187    expect(print(store)).toBe('');188  });189  it('should handle stress test with reordering (Concurrent Mode)', () => {190    const A = () => 'a';191    const B = () => 'b';192    const C = () => 'c';193    const D = () => 'd';194    const E = () => 'e';195    const a = <A key="a" />;196    const b = <B key="b" />;197    const c = <C key="c" />;198    const d = <D key="d" />;199    const e = <E key="e" />;200    // prettier-ignore201    const steps = [202      a,203      b,204      c,205      d,206      e,207      [a],208      [b],209      [c],210      [d],211      [e],212      [a, b],213      [b, a],214      [b, c],215      [c, b],216      [a, c],217      [c, a],218    ];219    const Root = ({children}) => {220      return children;221    };222    // 1. Capture the expected render result.223    const snapshots = [];224    let container = document.createElement('div');225    // $FlowFixMe226    let root = ReactDOM.createRoot(container);227    for (let i = 0; i < steps.length; i++) {228      act(() => root.render(<Root>{steps[i]}</Root>));229      // We snapshot each step once so it doesn't regress.230      snapshots.push(print(store));231      act(() => root.unmount());232      expect(print(store)).toBe('');233    }234    expect(snapshots).toMatchInlineSnapshot(`235      Array [236        "[root]237        ▾ <Root>238            <A key=\\"a\\">",239        "[root]240        ▾ <Root>241            <B key=\\"b\\">",242        "[root]243        ▾ <Root>244            <C key=\\"c\\">",245        "[root]246        ▾ <Root>247            <D key=\\"d\\">",248        "[root]249        ▾ <Root>250            <E key=\\"e\\">",251        "[root]252        ▾ <Root>253            <A key=\\"a\\">",254        "[root]255        ▾ <Root>256            <B key=\\"b\\">",257        "[root]258        ▾ <Root>259            <C key=\\"c\\">",260        "[root]261        ▾ <Root>262            <D key=\\"d\\">",263        "[root]264        ▾ <Root>265            <E key=\\"e\\">",266        "[root]267        ▾ <Root>268            <A key=\\"a\\">269            <B key=\\"b\\">",270        "[root]271        ▾ <Root>272            <B key=\\"b\\">273            <A key=\\"a\\">",274        "[root]275        ▾ <Root>276            <B key=\\"b\\">277            <C key=\\"c\\">",278        "[root]279        ▾ <Root>280            <C key=\\"c\\">281            <B key=\\"b\\">",282        "[root]283        ▾ <Root>284            <A key=\\"a\\">285            <C key=\\"c\\">",286        "[root]287        ▾ <Root>288            <C key=\\"c\\">289            <A key=\\"a\\">",290      ]291    `);292    // 2. Verify that we can update from every step to every other step and back.293    for (let i = 0; i < steps.length; i++) {294      for (let j = 0; j < steps.length; j++) {295        container = document.createElement('div');296        // $FlowFixMe297        root = ReactDOM.createRoot(container);298        act(() => root.render(<Root>{steps[i]}</Root>));299        expect(print(store)).toMatch(snapshots[i]);300        act(() => root.render(<Root>{steps[j]}</Root>));301        expect(print(store)).toMatch(snapshots[j]);302        act(() => root.render(<Root>{steps[i]}</Root>));303        expect(print(store)).toMatch(snapshots[i]);304        act(() => root.unmount());305        expect(print(store)).toBe('');306      }307    }308    // 3. Same test as above, but this time we wrap children in a host component.309    for (let i = 0; i < steps.length; i++) {310      for (let j = 0; j < steps.length; j++) {311        container = document.createElement('div');312        // $FlowFixMe313        root = ReactDOM.createRoot(container);314        act(() =>315          root.render(316            <Root>317              <div>{steps[i]}</div>318            </Root>,319          ),320        );321        expect(print(store)).toMatch(snapshots[i]);322        act(() =>323          root.render(324            <Root>325              <div>{steps[j]}</div>326            </Root>,327          ),328        );329        expect(print(store)).toMatch(snapshots[j]);330        act(() =>331          root.render(332            <Root>333              <div>{steps[i]}</div>334            </Root>,335          ),336        );337        expect(print(store)).toMatch(snapshots[i]);338        act(() => root.unmount());339        expect(print(store)).toBe('');340      }341    }342  });343  it('should handle a stress test for Suspense (Concurrent Mode)', async () => {344    const A = () => 'a';345    const B = () => 'b';346    const C = () => 'c';347    const X = () => 'x';348    const Y = () => 'y';349    const Z = () => 'z';350    const a = <A key="a" />;351    const b = <B key="b" />;352    const c = <C key="c" />;353    const z = <Z key="z" />;354    // prettier-ignore355    const steps = [356      a,357      [a],358      [a, b, c],359      [c, b, a],360      [c, null, a],361      <React.Fragment>{c}{a}</React.Fragment>,362      <div>{c}{a}</div>,363      <div><span>{a}</span>{b}</div>,364      [[a]],365      null,366      b,367      a,368    ];369    const Never = () => {370      throw new Promise(() => {});371    };372    const Root = ({children}) => {373      return children;374    };375    // 1. For each step, check Suspense can render them as initial primary content.376    // This is the only step where we use Jest snapshots.377    const snapshots = [];378    let container = document.createElement('div');379    // $FlowFixMe380    let root = ReactDOM.createRoot(container);381    for (let i = 0; i < steps.length; i++) {382      act(() =>383        root.render(384          <Root>385            <X />386            <React.Suspense fallback={z}>{steps[i]}</React.Suspense>387            <Y />388          </Root>,389        ),390      );391      // We snapshot each step once so it doesn't regress.d392      snapshots.push(print(store));393      act(() => root.unmount());394      expect(print(store)).toBe('');395    }396    expect(snapshots).toMatchInlineSnapshot(`397      Array [398        "[root]399        ▾ <Root>400            <X>401          ▾ <Suspense>402              <A key=\\"a\\">403            <Y>",404        "[root]405        ▾ <Root>406            <X>407          ▾ <Suspense>408              <A key=\\"a\\">409            <Y>",410        "[root]411        ▾ <Root>412            <X>413          ▾ <Suspense>414              <A key=\\"a\\">415              <B key=\\"b\\">416              <C key=\\"c\\">417            <Y>",418        "[root]419        ▾ <Root>420            <X>421          ▾ <Suspense>422              <C key=\\"c\\">423              <B key=\\"b\\">424              <A key=\\"a\\">425            <Y>",426        "[root]427        ▾ <Root>428            <X>429          ▾ <Suspense>430              <C key=\\"c\\">431              <A key=\\"a\\">432            <Y>",433        "[root]434        ▾ <Root>435            <X>436          ▾ <Suspense>437              <C key=\\"c\\">438              <A key=\\"a\\">439            <Y>",440        "[root]441        ▾ <Root>442            <X>443          ▾ <Suspense>444              <C key=\\"c\\">445              <A key=\\"a\\">446            <Y>",447        "[root]448        ▾ <Root>449            <X>450          ▾ <Suspense>451              <A key=\\"a\\">452              <B key=\\"b\\">453            <Y>",454        "[root]455        ▾ <Root>456            <X>457          ▾ <Suspense>458              <A key=\\"a\\">459            <Y>",460        "[root]461        ▾ <Root>462            <X>463            <Suspense>464            <Y>",465        "[root]466        ▾ <Root>467            <X>468          ▾ <Suspense>469              <B key=\\"b\\">470            <Y>",471        "[root]472        ▾ <Root>473            <X>474          ▾ <Suspense>475              <A key=\\"a\\">476            <Y>",477      ]478    `);479    // 2. Verify check Suspense can render same steps as initial fallback content.480    for (let i = 0; i < steps.length; i++) {481      act(() =>482        root.render(483          <Root>484            <X />485            <React.Suspense fallback={steps[i]}>486              <Z />487              <Never />488              <Z />489            </React.Suspense>490            <Y />491          </Root>,492        ),493      );494      expect(print(store)).toEqual(snapshots[i]);495      act(() => root.unmount());496      expect(print(store)).toBe('');497    }498    // 3. Verify we can update from each step to each step in primary mode.499    for (let i = 0; i < steps.length; i++) {500      for (let j = 0; j < steps.length; j++) {501        // Always start with a fresh container and steps[i].502        container = document.createElement('div');503        // $FlowFixMe504        root = ReactDOM.createRoot(container);505        act(() =>506          root.render(507            <Root>508              <X />509              <React.Suspense fallback={z}>{steps[i]}</React.Suspense>510              <Y />511            </Root>,512          ),513        );514        expect(print(store)).toEqual(snapshots[i]);515        // Re-render with steps[j].516        act(() =>517          root.render(518            <Root>519              <X />520              <React.Suspense fallback={z}>{steps[j]}</React.Suspense>521              <Y />522            </Root>,523          ),524        );525        // Verify the successful transition to steps[j].526        expect(print(store)).toEqual(snapshots[j]);527        // Check that we can transition back again.528        act(() =>529          root.render(530            <Root>531              <X />532              <React.Suspense fallback={z}>{steps[i]}</React.Suspense>533              <Y />534            </Root>,535          ),536        );537        expect(print(store)).toEqual(snapshots[i]);538        // Clean up after every iteration.539        act(() => root.unmount());540        expect(print(store)).toBe('');541      }542    }543    // 4. Verify we can update from each step to each step in fallback mode.544    for (let i = 0; i < steps.length; i++) {545      for (let j = 0; j < steps.length; j++) {546        // Always start with a fresh container and steps[i].547        container = document.createElement('div');548        // $FlowFixMe549        root = ReactDOM.createRoot(container);550        act(() =>551          root.render(552            <Root>553              <X />554              <React.Suspense fallback={steps[i]}>555                <Z />556                <Never />557                <Z />558              </React.Suspense>559              <Y />560            </Root>,561          ),562        );563        expect(print(store)).toEqual(snapshots[i]);564        // Re-render with steps[j].565        act(() =>566          root.render(567            <Root>568              <X />569              <React.Suspense fallback={steps[j]}>570                <Z />571                <Never />572                <Z />573              </React.Suspense>574              <Y />575            </Root>,576          ),577        );578        // Verify the successful transition to steps[j].579        expect(print(store)).toEqual(snapshots[j]);580        // Check that we can transition back again.581        act(() =>582          root.render(583            <Root>584              <X />585              <React.Suspense fallback={steps[i]}>586                <Z />587                <Never />588                <Z />589              </React.Suspense>590              <Y />591            </Root>,592          ),593        );594        expect(print(store)).toEqual(snapshots[i]);595        // Clean up after every iteration.596        act(() => root.unmount());597        expect(print(store)).toBe('');598      }599    }600    // 5. Verify we can update from each step to each step when moving primary -> fallback.601    for (let i = 0; i < steps.length; i++) {602      for (let j = 0; j < steps.length; j++) {603        // Always start with a fresh container and steps[i].604        container = document.createElement('div');605        // $FlowFixMe606        root = ReactDOM.createRoot(container);607        act(() =>608          root.render(609            <Root>610              <X />611              <React.Suspense fallback={z}>{steps[i]}</React.Suspense>612              <Y />613            </Root>,614          ),615        );616        expect(print(store)).toEqual(snapshots[i]);617        // Re-render with steps[j].618        act(() =>619          root.render(620            <Root>621              <X />622              <React.Suspense fallback={steps[j]}>623                <Z />624                <Never />625                <Z />626              </React.Suspense>627              <Y />628            </Root>,629          ),630        );631        // Verify the successful transition to steps[j].632        expect(print(store)).toEqual(snapshots[j]);633        // Check that we can transition back again.634        act(() =>635          root.render(636            <Root>637              <X />638              <React.Suspense fallback={z}>{steps[i]}</React.Suspense>639              <Y />640            </Root>,641          ),642        );643        expect(print(store)).toEqual(snapshots[i]);644        // Clean up after every iteration.645        act(() => root.unmount());646        expect(print(store)).toBe('');647      }648    }649    // 6. Verify we can update from each step to each step when moving fallback -> primary.650    for (let i = 0; i < steps.length; i++) {651      for (let j = 0; j < steps.length; j++) {652        // Always start with a fresh container and steps[i].653        container = document.createElement('div');654        // $FlowFixMe655        root = ReactDOM.createRoot(container);656        act(() =>657          root.render(658            <Root>659              <X />660              <React.Suspense fallback={steps[i]}>661                <Z />662                <Never />663                <Z />664              </React.Suspense>665              <Y />666            </Root>,667          ),668        );669        expect(print(store)).toEqual(snapshots[i]);670        // Re-render with steps[j].671        act(() =>672          root.render(673            <Root>674              <X />675              <React.Suspense fallback={z}>{steps[j]}</React.Suspense>676              <Y />677            </Root>,678          ),679        );680        // Verify the successful transition to steps[j].681        expect(print(store)).toEqual(snapshots[j]);682        // Check that we can transition back again.683        act(() =>684          root.render(685            <Root>686              <X />687              <React.Suspense fallback={steps[i]}>688                <Z />689                <Never />690                <Z />691              </React.Suspense>692              <Y />693            </Root>,694          ),695        );696        expect(print(store)).toEqual(snapshots[i]);697        // Clean up after every iteration.698        act(() => root.unmount());699        expect(print(store)).toBe('');700      }701    }702    // 7. Verify we can update from each step to each step when toggling Suspense.703    for (let i = 0; i < steps.length; i++) {704      for (let j = 0; j < steps.length; j++) {705        // Always start with a fresh container and steps[i].706        container = document.createElement('div');707        // $FlowFixMe708        root = ReactDOM.createRoot(container);709        act(() =>710          root.render(711            <Root>712              <X />713              <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>714              <Y />715            </Root>,716          ),717        );718        // We get ID from the index in the tree above:719        // Root, X, Suspense, ...720        //          ^ (index is 2)721        const suspenseID = store.getElementIDAtIndex(2);722        // Force fallback.723        expect(print(store)).toEqual(snapshots[i]);724        await actAsync(async () => {725          bridge.send('overrideSuspense', {726            id: suspenseID,727            rendererID: store.getRendererIDForElement(suspenseID),728            forceFallback: true,729          });730        });731        expect(print(store)).toEqual(snapshots[j]);732        // Stop forcing fallback.733        await actAsync(async () => {734          bridge.send('overrideSuspense', {735            id: suspenseID,736            rendererID: store.getRendererIDForElement(suspenseID),737            forceFallback: false,738          });739        });740        expect(print(store)).toEqual(snapshots[i]);741        // Trigger actual fallback.742        act(() =>743          root.render(744            <Root>745              <X />746              <React.Suspense fallback={steps[j]}>747                <Z />748                <Never />749                <Z />750              </React.Suspense>751              <Y />752            </Root>,753          ),754        );755        expect(print(store)).toEqual(snapshots[j]);756        // Force fallback while we're in fallback mode.757        act(() => {758          bridge.send('overrideSuspense', {759            id: suspenseID,760            rendererID: store.getRendererIDForElement(suspenseID),761            forceFallback: true,762          });763        });764        // Keep seeing fallback content.765        expect(print(store)).toEqual(snapshots[j]);766        // Switch to primary mode.767        act(() =>768          root.render(769            <Root>770              <X />771              <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>772              <Y />773            </Root>,774          ),775        );776        // Fallback is still forced though.777        expect(print(store)).toEqual(snapshots[j]);778        // Stop forcing fallback. This reverts to primary content.779        await actAsync(async () => {780          bridge.send('overrideSuspense', {781            id: suspenseID,782            rendererID: store.getRendererIDForElement(suspenseID),783            forceFallback: false,784          });785        });786        // Now we see primary content.787        expect(print(store)).toEqual(snapshots[i]);788        // Clean up after every iteration.789        await actAsync(async () => root.unmount());790        expect(print(store)).toBe('');791      }792    }793  });794  it('should handle a stress test for Suspense without type change (Concurrent Mode)', async () => {795    const A = () => 'a';796    const B = () => 'b';797    const C = () => 'c';798    const X = () => 'x';799    const Y = () => 'y';800    const Z = () => 'z';801    const a = <A key="a" />;802    const b = <B key="b" />;803    const c = <C key="c" />;804    const z = <Z key="z" />;805    // prettier-ignore806    const steps = [807      a,808      [a],809      [a, b, c],810      [c, b, a],811      [c, null, a],812      <React.Fragment>{c}{a}</React.Fragment>,813      <div>{c}{a}</div>,814      <div><span>{a}</span>{b}</div>,815      [[a]],816      null,817      b,818      a,819    ];820    const Never = () => {821      throw new Promise(() => {});822    };823    const MaybeSuspend = ({children, suspend}) => {824      if (suspend) {825        return (826          <div>827            {children}828            <Never />829            <X />830          </div>831        );832      }833      return (834        <div>835          {children}836          <Z />837        </div>838      );839    };840    const Root = ({children}) => {841      return children;842    };843    // 1. For each step, check Suspense can render them as initial primary content.844    // This is the only step where we use Jest snapshots.845    const snapshots = [];846    let container = document.createElement('div');847    // $FlowFixMe848    let root = ReactDOM.createRoot(container);849    for (let i = 0; i < steps.length; i++) {850      act(() =>851        root.render(852          <Root>853            <X />854            <React.Suspense fallback={z}>855              <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>856            </React.Suspense>857            <Y />858          </Root>,859        ),860      );861      // We snapshot each step once so it doesn't regress.862      snapshots.push(print(store));863      act(() => root.unmount());864      expect(print(store)).toBe('');865    }866    // 2. Verify check Suspense can render same steps as initial fallback content.867    // We don't actually assert here because the tree includes <MaybeSuspend>868    // which is different from the snapshots above. So we take more snapshots.869    const fallbackSnapshots = [];870    for (let i = 0; i < steps.length; i++) {871      act(() =>872        root.render(873          <Root>874            <X />875            <React.Suspense fallback={steps[i]}>876              <Z />877              <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>878              <Z />879            </React.Suspense>880            <Y />881          </Root>,882        ),883      );884      // We snapshot each step once so it doesn't regress.885      fallbackSnapshots.push(print(store));886      act(() => root.unmount());887      expect(print(store)).toBe('');888    }889    expect(snapshots).toMatchInlineSnapshot(`890      Array [891        "[root]892        ▾ <Root>893            <X>894          ▾ <Suspense>895            ▾ <MaybeSuspend>896                <A key=\\"a\\">897                <Z>898            <Y>",899        "[root]900        ▾ <Root>901            <X>902          ▾ <Suspense>903            ▾ <MaybeSuspend>904                <A key=\\"a\\">905                <Z>906            <Y>",907        "[root]908        ▾ <Root>909            <X>910          ▾ <Suspense>911            ▾ <MaybeSuspend>912                <A key=\\"a\\">913                <B key=\\"b\\">914                <C key=\\"c\\">915                <Z>916            <Y>",917        "[root]918        ▾ <Root>919            <X>920          ▾ <Suspense>921            ▾ <MaybeSuspend>922                <C key=\\"c\\">923                <B key=\\"b\\">924                <A key=\\"a\\">925                <Z>926            <Y>",927        "[root]928        ▾ <Root>929            <X>930          ▾ <Suspense>931            ▾ <MaybeSuspend>932                <C key=\\"c\\">933                <A key=\\"a\\">934                <Z>935            <Y>",936        "[root]937        ▾ <Root>938            <X>939          ▾ <Suspense>940            ▾ <MaybeSuspend>941                <C key=\\"c\\">942                <A key=\\"a\\">943                <Z>944            <Y>",945        "[root]946        ▾ <Root>947            <X>948          ▾ <Suspense>949            ▾ <MaybeSuspend>950                <C key=\\"c\\">951                <A key=\\"a\\">952                <Z>953            <Y>",954        "[root]955        ▾ <Root>956            <X>957          ▾ <Suspense>958            ▾ <MaybeSuspend>959                <A key=\\"a\\">960                <B key=\\"b\\">961                <Z>962            <Y>",963        "[root]964        ▾ <Root>965            <X>966          ▾ <Suspense>967            ▾ <MaybeSuspend>968                <A key=\\"a\\">969                <Z>970            <Y>",971        "[root]972        ▾ <Root>973            <X>974          ▾ <Suspense>975            ▾ <MaybeSuspend>976                <Z>977            <Y>",978        "[root]979        ▾ <Root>980            <X>981          ▾ <Suspense>982            ▾ <MaybeSuspend>983                <B key=\\"b\\">984                <Z>985            <Y>",986        "[root]987        ▾ <Root>988            <X>989          ▾ <Suspense>990            ▾ <MaybeSuspend>991                <A key=\\"a\\">992                <Z>993            <Y>",994      ]995    `);996    // 3. Verify we can update from each step to each step in primary mode.997    for (let i = 0; i < steps.length; i++) {998      for (let j = 0; j < steps.length; j++) {999        // Always start with a fresh container and steps[i].1000        container = document.createElement('div');1001        // $FlowFixMe1002        root = ReactDOM.createRoot(container);1003        act(() =>1004          root.render(1005            <Root>1006              <X />1007              <React.Suspense fallback={z}>1008                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1009              </React.Suspense>1010              <Y />1011            </Root>,1012          ),1013        );1014        expect(print(store)).toEqual(snapshots[i]);1015        // Re-render with steps[j].1016        act(() =>1017          root.render(1018            <Root>1019              <X />1020              <React.Suspense fallback={z}>1021                <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>1022              </React.Suspense>1023              <Y />1024            </Root>,1025          ),1026        );1027        // Verify the successful transition to steps[j].1028        expect(print(store)).toEqual(snapshots[j]);1029        // Check that we can transition back again.1030        act(() =>1031          root.render(1032            <Root>1033              <X />1034              <React.Suspense fallback={z}>1035                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1036              </React.Suspense>1037              <Y />1038            </Root>,1039          ),1040        );1041        expect(print(store)).toEqual(snapshots[i]);1042        // Clean up after every iteration.1043        act(() => root.unmount());1044        expect(print(store)).toBe('');1045      }1046    }1047    // 4. Verify we can update from each step to each step in fallback mode.1048    for (let i = 0; i < steps.length; i++) {1049      for (let j = 0; j < steps.length; j++) {1050        // Always start with a fresh container and steps[i].1051        container = document.createElement('div');1052        // $FlowFixMe1053        root = ReactDOM.createRoot(container);1054        act(() =>1055          root.render(1056            <Root>1057              <X />1058              <React.Suspense fallback={steps[i]}>1059                <Z />1060                <MaybeSuspend suspend={true}>1061                  <X />1062                  <Y />1063                </MaybeSuspend>1064                <Z />1065              </React.Suspense>1066              <Y />1067            </Root>,1068          ),1069        );1070        expect(print(store)).toEqual(fallbackSnapshots[i]);1071        // Re-render with steps[j].1072        act(() =>1073          root.render(1074            <Root>1075              <X />1076              <React.Suspense fallback={steps[j]}>1077                <Z />1078                <MaybeSuspend suspend={true}>1079                  <Y />1080                  <X />1081                </MaybeSuspend>1082                <Z />1083              </React.Suspense>1084              <Y />1085            </Root>,1086          ),1087        );1088        // Verify the successful transition to steps[j].1089        expect(print(store)).toEqual(fallbackSnapshots[j]);1090        // Check that we can transition back again.1091        act(() =>1092          root.render(1093            <Root>1094              <X />1095              <React.Suspense fallback={steps[i]}>1096                <Z />1097                <MaybeSuspend suspend={true}>1098                  <X />1099                  <Y />1100                </MaybeSuspend>1101                <Z />1102              </React.Suspense>1103              <Y />1104            </Root>,1105          ),1106        );1107        expect(print(store)).toEqual(fallbackSnapshots[i]);1108        // Clean up after every iteration.1109        act(() => root.unmount());1110        expect(print(store)).toBe('');1111      }1112    }1113    // 5. Verify we can update from each step to each step when moving primary -> fallback.1114    for (let i = 0; i < steps.length; i++) {1115      for (let j = 0; j < steps.length; j++) {1116        // Always start with a fresh container and steps[i].1117        container = document.createElement('div');1118        // $FlowFixMe1119        root = ReactDOM.createRoot(container);1120        act(() =>1121          root.render(1122            <Root>1123              <X />1124              <React.Suspense fallback={z}>1125                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1126              </React.Suspense>1127              <Y />1128            </Root>,1129          ),1130        );1131        expect(print(store)).toEqual(snapshots[i]);1132        // Re-render with steps[j].1133        act(() =>1134          root.render(1135            <Root>1136              <X />1137              <React.Suspense fallback={steps[j]}>1138                <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>1139              </React.Suspense>1140              <Y />1141            </Root>,1142          ),1143        );1144        // Verify the successful transition to steps[j].1145        expect(print(store)).toEqual(fallbackSnapshots[j]);1146        // Check that we can transition back again.1147        act(() =>1148          root.render(1149            <Root>1150              <X />1151              <React.Suspense fallback={z}>1152                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1153              </React.Suspense>1154              <Y />1155            </Root>,1156          ),1157        );1158        expect(print(store)).toEqual(snapshots[i]);1159        // Clean up after every iteration.1160        act(() => root.unmount());1161        expect(print(store)).toBe('');1162      }1163    }1164    // 6. Verify we can update from each step to each step when moving fallback -> primary.1165    for (let i = 0; i < steps.length; i++) {1166      for (let j = 0; j < steps.length; j++) {1167        // Always start with a fresh container and steps[i].1168        container = document.createElement('div');1169        // $FlowFixMe1170        root = ReactDOM.createRoot(container);1171        act(() =>1172          root.render(1173            <Root>1174              <X />1175              <React.Suspense fallback={steps[i]}>1176                <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>1177              </React.Suspense>1178              <Y />1179            </Root>,1180          ),1181        );1182        expect(print(store)).toEqual(fallbackSnapshots[i]);1183        // Re-render with steps[j].1184        act(() =>1185          root.render(1186            <Root>1187              <X />1188              <React.Suspense fallback={steps[i]}>1189                <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>1190              </React.Suspense>1191              <Y />1192            </Root>,1193          ),1194        );1195        // Verify the successful transition to steps[j].1196        expect(print(store)).toEqual(snapshots[j]);1197        // Check that we can transition back again.1198        act(() =>1199          root.render(1200            <Root>1201              <X />1202              <React.Suspense fallback={steps[i]}>1203                <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>1204              </React.Suspense>1205              <Y />1206            </Root>,1207          ),1208        );1209        expect(print(store)).toEqual(fallbackSnapshots[i]);1210        // Clean up after every iteration.1211        act(() => root.unmount());1212        expect(print(store)).toBe('');1213      }1214    }1215    // 7. Verify we can update from each step to each step when toggling Suspense.1216    for (let i = 0; i < steps.length; i++) {1217      for (let j = 0; j < steps.length; j++) {1218        // Always start with a fresh container and steps[i].1219        container = document.createElement('div');1220        // $FlowFixMe1221        root = ReactDOM.createRoot(container);1222        act(() =>1223          root.render(1224            <Root>1225              <X />1226              <React.Suspense fallback={steps[j]}>1227                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1228              </React.Suspense>1229              <Y />1230            </Root>,1231          ),1232        );1233        // We get ID from the index in the tree above:1234        // Root, X, Suspense, ...1235        //          ^ (index is 2)1236        const suspenseID = store.getElementIDAtIndex(2);1237        // Force fallback.1238        expect(print(store)).toEqual(snapshots[i]);1239        await actAsync(async () => {1240          bridge.send('overrideSuspense', {1241            id: suspenseID,1242            rendererID: store.getRendererIDForElement(suspenseID),1243            forceFallback: true,1244          });1245        });1246        expect(print(store)).toEqual(fallbackSnapshots[j]);1247        // Stop forcing fallback.1248        await actAsync(async () => {1249          bridge.send('overrideSuspense', {1250            id: suspenseID,1251            rendererID: store.getRendererIDForElement(suspenseID),1252            forceFallback: false,1253          });1254        });1255        expect(print(store)).toEqual(snapshots[i]);1256        // Trigger actual fallback.1257        act(() =>1258          root.render(1259            <Root>1260              <X />1261              <React.Suspense fallback={steps[j]}>1262                <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>1263              </React.Suspense>1264              <Y />1265            </Root>,1266          ),1267        );1268        expect(print(store)).toEqual(fallbackSnapshots[j]);1269        // Force fallback while we're in fallback mode.1270        act(() => {1271          bridge.send('overrideSuspense', {1272            id: suspenseID,1273            rendererID: store.getRendererIDForElement(suspenseID),1274            forceFallback: true,1275          });1276        });1277        // Keep seeing fallback content.1278        expect(print(store)).toEqual(fallbackSnapshots[j]);1279        // Switch to primary mode.1280        act(() =>1281          root.render(1282            <Root>1283              <X />1284              <React.Suspense fallback={steps[j]}>1285                <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1286              </React.Suspense>1287              <Y />1288            </Root>,1289          ),1290        );1291        // Fallback is still forced though.1292        expect(print(store)).toEqual(fallbackSnapshots[j]);1293        // Stop forcing fallback. This reverts to primary content.1294        await actAsync(async () => {1295          bridge.send('overrideSuspense', {1296            id: suspenseID,1297            rendererID: store.getRendererIDForElement(suspenseID),1298            forceFallback: false,1299          });1300        });1301        // Now we see primary content.1302        expect(print(store)).toEqual(snapshots[i]);1303        // Clean up after every iteration.1304        act(() => root.unmount());1305        expect(print(store)).toBe('');1306      }1307    }1308  });...

Full Screen

Full Screen

DependencyGraph-test.js

Source:DependencyGraph-test.js Github

copy

Full Screen

1'use strict';2jest3  .dontMock('../index')4  .dontMock('q')5  .dontMock('path')6  .dontMock('absolute-path')7  .dontMock('../docblock')8  .setMock('../../../ModuleDescriptor', function(data) {return data;});9describe('DependencyGraph', function() {10  var DependencyGraph;11  var fileWatcher;12  var fs;13  beforeEach(function() {14    fs = require('fs');15    DependencyGraph = require('../index');16    fileWatcher = {17      on: function() {18        return this;19      }20    };21  });22  describe('getOrderedDependencies', function() {23    pit('should get dependencies', function() {24      var root = '/root';25      fs.__setMockFilesystem({26        'root': {27          'index.js': [28            '/**',29            ' * @providesModule index',30            ' */',31            'require("a")'32          ].join('\n'),33          'a.js': [34            '/**',35            ' * @providesModule a',36            ' */',37          ].join('\n'),38        }39      });40      var dgraph = new DependencyGraph({41        roots: [root],42        fileWatcher: fileWatcher43      });44      return dgraph.load().then(function() {45        expect(dgraph.getOrderedDependencies('/root/index.js'))46          .toEqual([47            {id: 'index', path: '/root/index.js', dependencies: ['a']},48            {id: 'a', path: '/root/a.js', dependencies: []},49          ]);50      });51    });52    pit('should get dependencies', function() {53      var root = '/root';54      fs.__setMockFilesystem({55        'root': {56          'index.js': [57            '/**',58            ' * @providesModule index',59            ' */',60            'require("image!a")'61          ].join('\n'),62          'imgs': {63            'a.png': ''64          },65        }66      });67      var dgraph = new DependencyGraph({68        roots: [root],69        fileWatcher: fileWatcher,70        assetRoots: ['/root/imgs']71      });72      return dgraph.load().then(function() {73        expect(dgraph.getOrderedDependencies('/root/index.js'))74          .toEqual([75            {id: 'index', path: '/root/index.js', dependencies: ['image!a']},76            {  id: 'image!a',77               path: '/root/imgs/a.png',78               dependencies: [],79               isAsset: true80            },81          ]);82      });83    });84    pit('should get recursive dependencies', function() {85      var root = '/root';86      fs.__setMockFilesystem({87        'root': {88          'index.js': [89            '/**',90            ' * @providesModule index',91            ' */',92            'require("a")',93          ].join('\n'),94          'a.js': [95            '/**',96            ' * @providesModule a',97            ' */',98            'require("index")',99          ].join('\n'),100        }101      });102      var dgraph = new DependencyGraph({103        roots: [root],104        fileWatcher: fileWatcher105      });106      return dgraph.load().then(function() {107        expect(dgraph.getOrderedDependencies('/root/index.js'))108          .toEqual([109            {id: 'index', path: '/root/index.js', dependencies: ['a']},110            {id: 'a', path: '/root/a.js', dependencies: ['index']},111          ]);112      });113    });114    pit('should work with packages', function() {115      var root = '/root';116      fs.__setMockFilesystem({117        'root': {118          'index.js': [119            '/**',120            ' * @providesModule index',121            ' */',122            'require("aPackage")',123          ].join('\n'),124          'aPackage': {125            'package.json': JSON.stringify({126              name: 'aPackage',127              main: 'main.js'128            }),129            'main.js': 'lol'130          }131        }132      });133      var dgraph = new DependencyGraph({134        roots: [root],135        fileWatcher: fileWatcher136      });137      return dgraph.load().then(function() {138        expect(dgraph.getOrderedDependencies('/root/index.js'))139          .toEqual([140            {id: 'index', path: '/root/index.js', dependencies: ['aPackage']},141            { id: 'aPackage/main',142              path: '/root/aPackage/main.js',143              dependencies: []144            },145          ]);146      });147    });148    pit('should ignore malformed packages', function() {149      var root = '/root';150      fs.__setMockFilesystem({151        'root': {152          'index.js': [153            '/**',154            ' * @providesModule index',155            ' */',156            'require("aPackage")',157          ].join('\n'),158          'aPackage': {159            'package.json': 'lol',160            'main.js': 'lol'161          }162        }163      });164      var dgraph = new DependencyGraph({165        roots: [root],166        fileWatcher: fileWatcher167      });168      return dgraph.load().then(function() {169        expect(dgraph.getOrderedDependencies('/root/index.js'))170          .toEqual([171            {id: 'index', path: '/root/index.js', dependencies: ['aPackage']},172          ]);173      });174    });175    pit('can have multiple modules with the same name', function() {176      var root = '/root';177      fs.__setMockFilesystem({178        'root': {179          'index.js': [180            '/**',181            ' * @providesModule index',182            ' */',183            'require("b")',184          ].join('\n'),185          'b.js': [186            '/**',187            ' * @providesModule b',188            ' */',189          ].join('\n'),190          'c.js': [191            '/**',192            ' * @providesModule c',193            ' */',194          ].join('\n'),195          'somedir': {196            'somefile.js': [197              '/**',198              ' * @providesModule index',199              ' */',200              'require("c")',201            ].join('\n')202          }203        }204      });205      var dgraph = new DependencyGraph({206        roots: [root],207        fileWatcher: fileWatcher208      });209      return dgraph.load().then(function() {210        expect(dgraph.getOrderedDependencies('/root/somedir/somefile.js'))211          .toEqual([212            { id: 'index',213              path: '/root/somedir/somefile.js',214              dependencies: ['c']215            },216            { id: 'c',217              path: '/root/c.js',218              dependencies: []219            },220          ]);221      });222    });223    pit('providesModule wins when conflict with package', function() {224      var root = '/root';225      fs.__setMockFilesystem({226        'root': {227          'index.js': [228            '/**',229            ' * @providesModule index',230            ' */',231            'require("aPackage")',232          ].join('\n'),233          'b.js': [234            '/**',235            ' * @providesModule aPackage',236            ' */',237          ].join('\n'),238          'aPackage': {239            'package.json': JSON.stringify({240              name: 'aPackage',241              main: 'main.js'242            }),243            'main.js': 'lol'244          }245        }246      });247      var dgraph = new DependencyGraph({248        roots: [root],249        fileWatcher: fileWatcher250      });251      return dgraph.load().then(function() {252        expect(dgraph.getOrderedDependencies('/root/index.js'))253          .toEqual([254            { id: 'index',255              path: '/root/index.js',256              dependencies: ['aPackage']257            },258            { id: 'aPackage',259              path: '/root/b.js',260              dependencies: []261            },262          ]);263      });264    });265    pit('should be forgiving with missing requires', function() {266      var root = '/root';267      fs.__setMockFilesystem({268        'root': {269          'index.js': [270            '/**',271            ' * @providesModule index',272            ' */',273            'require("lolomg")',274          ].join('\n')275        }276      });277      var dgraph = new DependencyGraph({278        roots: [root],279        fileWatcher: fileWatcher280      });281      return dgraph.load().then(function() {282        expect(dgraph.getOrderedDependencies('/root/index.js'))283          .toEqual([284            { id: 'index',285              path: '/root/index.js',286              dependencies: ['lolomg']287            }288          ]);289      });290    });291    pit('should work with packages with subdirs', function() {292      var root = '/root';293      fs.__setMockFilesystem({294        'root': {295          'index.js': [296            '/**',297            ' * @providesModule index',298            ' */',299            'require("aPackage/subdir/lolynot")',300          ].join('\n'),301          'aPackage': {302            'package.json': JSON.stringify({303              name: 'aPackage',304              main: 'main.js'305            }),306            'main.js': 'lol',307            'subdir': {308              'lolynot.js': 'lolynot'309            }310          }311        }312      });313      var dgraph = new DependencyGraph({314        roots: [root],315        fileWatcher: fileWatcher316      });317      return dgraph.load().then(function() {318        expect(dgraph.getOrderedDependencies('/root/index.js'))319          .toEqual([320            { id: 'index',321              path: '/root/index.js',322              dependencies: ['aPackage/subdir/lolynot']323            },324            { id: 'aPackage/subdir/lolynot',325              path: '/root/aPackage/subdir/lolynot.js',326              dependencies: []327            },328          ]);329      });330    });331    pit('should work with packages with symlinked subdirs', function() {332      var root = '/root';333      fs.__setMockFilesystem({334        'symlinkedPackage': {335          'package.json': JSON.stringify({336            name: 'aPackage',337            main: 'main.js'338          }),339          'main.js': 'lol',340          'subdir': {341            'lolynot.js': 'lolynot'342          }343        },344        'root': {345          'index.js': [346            '/**',347            ' * @providesModule index',348            ' */',349            'require("aPackage/subdir/lolynot")',350          ].join('\n'),351          'aPackage': { SYMLINK: '/symlinkedPackage' },352        }353      });354      var dgraph = new DependencyGraph({355        roots: [root],356        fileWatcher: fileWatcher357      });358      return dgraph.load().then(function() {359        expect(dgraph.getOrderedDependencies('/root/index.js'))360          .toEqual([361            { id: 'index',362              path: '/root/index.js',363              dependencies: ['aPackage/subdir/lolynot']364            },365            { id: 'aPackage/subdir/lolynot',366              path: '/symlinkedPackage/subdir/lolynot.js',367              dependencies: []368            },369          ]);370      });371    });372    pit('should work with relative modules in packages', function() {373      var root = '/root';374      fs.__setMockFilesystem({375        'root': {376          'index.js': [377            '/**',378            ' * @providesModule index',379            ' */',380            'require("aPackage")',381          ].join('\n'),382          'aPackage': {383            'package.json': JSON.stringify({384              name: 'aPackage',385              main: 'main.js'386            }),387            'main.js': 'require("./subdir/lolynot")',388            'subdir': {389              'lolynot.js': 'require("../other")'390            },391            'other.js': 'some code'392          }393        }394      });395      var dgraph = new DependencyGraph({396        roots: [root],397        fileWatcher: fileWatcher398      });399      return dgraph.load().then(function() {400        expect(dgraph.getOrderedDependencies('/root/index.js'))401          .toEqual([402            { id: 'index',403              path: '/root/index.js',404              dependencies: ['aPackage']405            },406            { id: 'aPackage/main',407              path: '/root/aPackage/main.js',408              dependencies: ['./subdir/lolynot']409            },410            { id: 'aPackage/subdir/lolynot',411              path: '/root/aPackage/subdir/lolynot.js',412              dependencies: ['../other']413            },414            { id: 'aPackage/other',415              path: '/root/aPackage/other.js',416              dependencies: []417            },418          ]);419      });420    });421  });422  describe('file watch updating', function() {423    var triggerFileChange;424    beforeEach(function() {425      fileWatcher = {426        on: function(eventType, callback) {427          if (eventType !== 'all') {428            throw new Error('Can only handle "all" event in watcher.');429          }430          triggerFileChange = callback;431          return this;432        }433      };434    });435    pit('updates module dependencies', function() {436      var root = '/root';437      var filesystem = fs.__setMockFilesystem({438        'root': {439          'index.js': [440            '/**',441            ' * @providesModule index',442            ' */',443            'require("aPackage")',444            'require("foo")'445          ].join('\n'),446          'foo': [447            '/**',448            ' * @providesModule foo',449            ' */',450            'require("aPackage")'451          ].join('\n'),452          'aPackage': {453            'package.json': JSON.stringify({454              name: 'aPackage',455              main: 'main.js'456            }),457            'main.js': 'main',458          }459        }460      });461      var dgraph = new DependencyGraph({462        roots: [root],463        fileWatcher: fileWatcher464      });465      return dgraph.load().then(function() {466        filesystem.root['index.js'] =467          filesystem.root['index.js'].replace('require("foo")', '');468        triggerFileChange('change', 'index.js', root);469        return dgraph.load().then(function() {470          expect(dgraph.getOrderedDependencies('/root/index.js'))471            .toEqual([472            { id: 'index',473              path: '/root/index.js',474              dependencies: ['aPackage']475            },476            { id: 'aPackage/main',477              path: '/root/aPackage/main.js',478              dependencies: []479            },480          ]);481        });482      });483    });484    pit('updates module dependencies on file change', function() {485      var root = '/root';486      var filesystem = fs.__setMockFilesystem({487        'root': {488          'index.js': [489            '/**',490            ' * @providesModule index',491            ' */',492            'require("aPackage")',493            'require("foo")'494          ].join('\n'),495          'foo.js': [496            '/**',497            ' * @providesModule foo',498            ' */',499            'require("aPackage")'500          ].join('\n'),501          'aPackage': {502            'package.json': JSON.stringify({503              name: 'aPackage',504              main: 'main.js'505            }),506            'main.js': 'main',507          }508        }509      });510      var dgraph = new DependencyGraph({511        roots: [root],512        fileWatcher: fileWatcher513      });514      return dgraph.load().then(function() {515        filesystem.root['index.js'] =516          filesystem.root['index.js'].replace('require("foo")', '');517        triggerFileChange('change', 'index.js', root);518        return dgraph.load().then(function() {519          expect(dgraph.getOrderedDependencies('/root/index.js'))520            .toEqual([521            { id: 'index',522              path: '/root/index.js',523              dependencies: ['aPackage']524            },525            { id: 'aPackage/main',526              path: '/root/aPackage/main.js',527              dependencies: []528            },529          ]);530        });531      });532    });533    pit('updates module dependencies on file delete', function() {534      var root = '/root';535      var filesystem = fs.__setMockFilesystem({536        'root': {537          'index.js': [538            '/**',539            ' * @providesModule index',540            ' */',541            'require("aPackage")',542            'require("foo")'543          ].join('\n'),544          'foo.js': [545            '/**',546            ' * @providesModule foo',547            ' */',548            'require("aPackage")'549          ].join('\n'),550          'aPackage': {551            'package.json': JSON.stringify({552              name: 'aPackage',553              main: 'main.js'554            }),555            'main.js': 'main',556          }557        }558      });559      var dgraph = new DependencyGraph({560        roots: [root],561        fileWatcher: fileWatcher562      });563      return dgraph.load().then(function() {564        delete filesystem.root.foo;565        triggerFileChange('delete', 'foo.js', root);566        return dgraph.load().then(function() {567          expect(dgraph.getOrderedDependencies('/root/index.js'))568            .toEqual([569            { id: 'index',570              path: '/root/index.js',571              dependencies: ['aPackage', 'foo']572            },573            { id: 'aPackage/main',574              path: '/root/aPackage/main.js',575              dependencies: []576            },577          ]);578        });579      });580    });581    pit('updates module dependencies on file add', function() {582      var root = '/root';583      var filesystem = fs.__setMockFilesystem({584        'root': {585          'index.js': [586            '/**',587            ' * @providesModule index',588            ' */',589            'require("aPackage")',590            'require("foo")'591          ].join('\n'),592          'foo.js': [593            '/**',594            ' * @providesModule foo',595            ' */',596            'require("aPackage")'597          ].join('\n'),598          'aPackage': {599            'package.json': JSON.stringify({600              name: 'aPackage',601              main: 'main.js'602            }),603            'main.js': 'main',604          }605        }606      });607      var dgraph = new DependencyGraph({608        roots: [root],609        fileWatcher: fileWatcher610      });611      return dgraph.load().then(function() {612        filesystem.root['bar.js'] = [613          '/**',614          ' * @providesModule bar',615          ' */',616          'require("foo")'617        ].join('\n');618        triggerFileChange('add', 'bar.js', root);619        filesystem.root.aPackage['main.js'] = 'require("bar")';620        triggerFileChange('change', 'aPackage/main.js', root);621        return dgraph.load().then(function() {622          expect(dgraph.getOrderedDependencies('/root/index.js'))623            .toEqual([624            { id: 'index',625              path: '/root/index.js',626              dependencies: ['aPackage', 'foo']627            },628            { id: 'aPackage/main',629              path: '/root/aPackage/main.js',630              dependencies: ['bar']631            },632            { id: 'bar',633              path: '/root/bar.js',634              dependencies: ['foo']635            },636            { id: 'foo',637              path: '/root/foo.js',638              dependencies: ['aPackage']639            },640          ]);641        });642      });643    });644    pit('runs changes through ignore filter', function() {645      var root = '/root';646      var filesystem = fs.__setMockFilesystem({647        'root': {648          'index.js': [649            '/**',650            ' * @providesModule index',651            ' */',652            'require("aPackage")',653            'require("foo")'654          ].join('\n'),655          'foo.js': [656            '/**',657            ' * @providesModule foo',658            ' */',659            'require("aPackage")'660          ].join('\n'),661          'aPackage': {662            'package.json': JSON.stringify({663              name: 'aPackage',664              main: 'main.js'665            }),666            'main.js': 'main',667          }668        }669      });670      var dgraph = new DependencyGraph({671        roots: [root],672        fileWatcher: fileWatcher,673        ignoreFilePath: function(filePath) {674          if (filePath === '/root/bar.js') {675            return true;676          }677          return false;678        }679      });680      return dgraph.load().then(function() {681        filesystem.root['bar.js'] = [682          '/**',683          ' * @providesModule bar',684          ' */',685          'require("foo")'686        ].join('\n');687        triggerFileChange('add', 'bar.js', root);688        filesystem.root.aPackage['main.js'] = 'require("bar")';689        triggerFileChange('change', 'aPackage/main.js', root);690        return dgraph.load().then(function() {691          expect(dgraph.getOrderedDependencies('/root/index.js'))692            .toEqual([693              { id: 'index',694                path: '/root/index.js',695                dependencies: ['aPackage', 'foo']696              },697              { id: 'aPackage/main',698                path: '/root/aPackage/main.js',699                dependencies: ['bar']700              },701              { id: 'foo',702                path: '/root/foo.js',703                dependencies: ['aPackage']704              },705            ]);706        });707      });708    });709    pit('should ignore directory updates', function() {710      var root = '/root';711      fs.__setMockFilesystem({712        'root': {713          'index.js': [714            '/**',715            ' * @providesModule index',716            ' */',717            'require("aPackage")',718            'require("foo")'719          ].join('\n'),720          'foo.js': [721            '/**',722            ' * @providesModule foo',723            ' */',724            'require("aPackage")'725          ].join('\n'),726          'aPackage': {727            'package.json': JSON.stringify({728              name: 'aPackage',729              main: 'main.js'730            }),731            'main.js': 'main',732          }733        }734      });735      var dgraph = new DependencyGraph({736        roots: [root],737        fileWatcher: fileWatcher738      });739      return dgraph.load().then(function() {740        triggerFileChange('change', 'aPackage', '/root', {741          isDirectory: function(){ return true; }742        });743        return dgraph.load().then(function() {744          expect(dgraph.getOrderedDependencies('/root/index.js'))745            .toEqual([746              { id: 'index',747                path: '/root/index.js',748                dependencies: ['aPackage', 'foo']749              },750              { id: 'aPackage/main',751                path: '/root/aPackage/main.js',752                dependencies: []753              },754              { id: 'foo',755                path: '/root/foo.js',756                dependencies: ['aPackage']757              },758            ]);759        });760      });761    });762  });...

Full Screen

Full Screen

Node.js

Source:Node.js Github

copy

Full Screen

1module("tinymce.html.Node");2test('construction', function() {3	var node;4	expect(15);5	node = new tinymce.html.Node('#text', 3);6	equal(node.name, '#text');7	equal(node.type, 3);8	node = new tinymce.html.Node('#comment', 8);9	equal(node.name, '#comment');10	equal(node.type, 8);11	node = new tinymce.html.Node('b', 1);12	equal(node.name, 'b');13	equal(node.type, 1);14	deepEqual(node.attributes, []);15	node = new tinymce.html.Node('#pi', 7);16	equal(node.name, '#pi');17	equal(node.type, 7);18	node = new tinymce.html.Node('#doctype', 10);19	equal(node.name, '#doctype');20	equal(node.type, 10);21	node = new tinymce.html.Node('#cdata', 4);22	equal(node.name, '#cdata');23	equal(node.type, 4);24	node = new tinymce.html.Node('#frag', 11);25	equal(node.name, '#frag');26	equal(node.type, 11);27});28test('append inside empty node', function() {29	var root, node;30	expect(10);31	root = new tinymce.html.Node('#frag', 11);32	node = root.append(new tinymce.html.Node('b', 1));33	ok(root.firstChild.parent === root);34	equal(root.firstChild.next, undefined);35	equal(root.firstChild.prev, undefined);36	equal(root.firstChild.firstChild, undefined);37	equal(root.firstChild.lastChild, undefined);38	ok(node.parent === root);39	equal(node.next, undefined);40	equal(node.prev, undefined);41	equal(node.firstChild, undefined);42	equal(node.lastChild, undefined);43});44test('append node after node', function() {45	var root, node, node2;46	expect(17);47	root = new tinymce.html.Node('#frag', 11);48	node2 = root.append(new tinymce.html.Node('a', 1));49	node = root.append(new tinymce.html.Node('b', 1));50	ok(root.firstChild.parent === root, 'root.firstChild.parent === root');51	ok(root.firstChild === node2, 'root.firstChild');52	ok(root.lastChild === node, 'root.firstChild');53	ok(root.firstChild.next === node, 'root.firstChild.next');54	equal(root.firstChild.prev, undefined, 'root.firstChild.prev');55	equal(root.firstChild.firstChild, undefined, 'root.firstChild.firstChild');56	equal(root.firstChild.lastChild, undefined, 'root.firstChild.lastChild');57	ok(node2.parent === root, 'node2.parent === root');58	ok(node2.next === node, 'node2.next');59	equal(node2.prev, undefined, 'node2.prev');60	equal(node2.firstChild, undefined, 'node2.firstChild');61	equal(node2.lastChild, undefined, 'node2.lastChild');62	ok(node.parent === root, 'node.parent === root');63	equal(node.next, undefined, 'node.next');64	ok(node.prev === node2, 'node.prev');65	equal(node.firstChild, undefined, 'node.firstChild');66	equal(node.lastChild, undefined, 'node.lastChild');67});68test('append existing node before other existing node', function() {69	var root, node, node2;70	expect(8);71	root = new tinymce.html.Node('#frag', 11);72	node = root.append(new tinymce.html.Node('a', 1));73	node2 = root.append(new tinymce.html.Node('b', 1));74	root.append(node);75	ok(root.firstChild === node2, 'root.firstChild');76	ok(root.lastChild === node, 'root.lastChild');77	equal(node.next, undefined, 'node.next');78	ok(node.prev === node2, 'node.prev');79	ok(node.parent === root, 'node.parent');80	ok(node2.parent === root, 'node2.parent');81	equal(node2.prev, undefined, 'node2.prev');82	ok(node2.next === node, 'node2.next');83});84test('remove unattached node', function() {85	expect(1);86	ok(!new tinymce.html.Node('#text', 3).remove().parent);87});88test('remove single child', function() {89	var root, node;90	expect(6);91	root = new tinymce.html.Node('#frag', 11);92	node = root.append(new tinymce.html.Node('p', 1));93	node = root.firstChild.remove();94	equal(root.firstChild, undefined);95	equal(root.lastChild, undefined);96	equal(node.parent, undefined);97	equal(node.next, undefined);98	equal(node.prev, undefined);99	equal(node.name, 'p');100});101test('remove middle node', function() {102	var root, node, node2, node3;103	expect(9);104	root = new tinymce.html.Node('#frag', 11);105	node = root.append(new tinymce.html.Node('a', 1));106	node2 = root.append(new tinymce.html.Node('b', 1));107	node3 = root.append(new tinymce.html.Node('c', 1));108	node2.remove();109	equal(node2.parent, undefined);110	equal(node2.next, undefined);111	equal(node2.prev, undefined);112	ok(root.firstChild === node, 'root.firstChild');113	ok(root.lastChild === node3, 'root.lastChild');114	ok(node.next === node3, 'node.next');115	equal(node.prev, undefined, 'node.prev');116	ok(node3.prev, node, 'node3.prev');117	equal(node3.next, undefined, 'node3.next');118});119test('insert after last', function() {120	var fragment, root, node, node2;121	expect(5);122	fragment = new tinymce.html.Node('#frag', 11);123	root = fragment.append(new tinymce.html.Node('body', 1));124	node = root.append(new tinymce.html.Node('a', 1));125	node2 = root.insert(new tinymce.html.Node('x', 1), node);126	ok(root.firstChild === node, 'root.firstChild');127	ok(root.lastChild === node2, 'root.lastChild');128	ok(node.next === node2, 'node.next');129	ok(node2.prev === node, 'node2.prev');130	ok(node2.parent === root, 'node3.next');131});132test('insert before first', function() {133	var fragment, root, node, node2;134	expect(8);135	fragment = new tinymce.html.Node('#frag', 11);136	root = fragment.append(new tinymce.html.Node('body', 1));137	node = root.append(new tinymce.html.Node('a', 1));138	node2 = root.insert(new tinymce.html.Node('x', 1), node, true);139	ok(root.firstChild === node2, 'root.firstChild');140	ok(root.lastChild === node, 'root.lastChild');141	ok(node2.parent === root, 'node2.lastChild');142	ok(node2.next === node, 'node2.next');143	ok(node2.prev === undefined, 'node2.prev');144	ok(node.parent === root, 'node.lastChild');145	ok(node.next === undefined, 'node.next');146	ok(node.prev === node2, 'node.prev');147});148test('insert before second', function() {149	var fragment, root, node, node2, node3;150	expect(5);151	fragment = new tinymce.html.Node('#frag', 11);152	root = fragment.append(new tinymce.html.Node('body', 1));153	node = root.append(new tinymce.html.Node('a', 1));154	node2 = root.append(new tinymce.html.Node('b', 1));155	node3 = root.insert(new tinymce.html.Node('x', 1), node2, true);156	ok(root.firstChild === node, 'root.firstChild');157	ok(root.lastChild === node2, 'root.lastChild');158	ok(node3.parent === root, 'node3.parent');159	ok(node3.next === node2, 'node3.next');160	ok(node3.prev === node, 'node3.prev');161});162test('insert after and between two nodes', function() {163	var root, node, node2, node3, fragment;164	expect(7);165	fragment = new tinymce.html.Node('#frag', 11);166	root = fragment.append(new tinymce.html.Node('body', 1));167	node = root.append(new tinymce.html.Node('a', 1));168	node2 = root.append(new tinymce.html.Node('b', 1));169	node3 = root.insert(new tinymce.html.Node('x', 1), node);170	ok(root.firstChild === node, 'root.firstChild');171	ok(root.lastChild === node2, 'root.lastChild');172	ok(node.next === node3, 'node.next');173	ok(node2.prev === node3, 'node2.prev');174	ok(node3.parent === root, 'node3.next');175	ok(node3.next === node2, 'node3.next');176	ok(node3.prev === node, 'node3.prev');177});178test('replace single child', function() {179	var root, node1, node2;180	expect(5);181	root = new tinymce.html.Node('#frag', 11);182	node1 = root.append(new tinymce.html.Node('b', 1));183	node2 = root.append(new tinymce.html.Node('em', 1));184	node1.replace(node2);185	ok(root.firstChild === node2, 'root.firstChild');186	ok(root.lastChild === node2, 'root.lastChild');187	ok(node2.parent === root, 'node2.parent');188	ok(!node2.next, 'node2.next');189	ok(!node2.prev, 'node2.prev');190});191test('replace first child', function() {192	var root, node1, node2, node3;193	expect(5);194	root = new tinymce.html.Node('#frag', 11);195	node1 = root.append(new tinymce.html.Node('b', 1));196	node2 = root.append(new tinymce.html.Node('em', 1));197	node3 = root.append(new tinymce.html.Node('b', 1));198	node1.replace(node2);199	ok(root.firstChild === node2, 'root.firstChild');200	ok(root.lastChild === node3, 'root.lastChild');201	ok(node2.parent === root, 'node2.parent');202	ok(node2.next === node3, 'node2.next');203	ok(!node2.prev, 'node2.prev');204});205test('replace last child', function() {206	var root, node1, node2, node3;207	expect(5);208	root = new tinymce.html.Node('#frag', 11);209	node1 = root.append(new tinymce.html.Node('b', 1));210	node3 = root.append(new tinymce.html.Node('b', 1));211	node2 = root.append(new tinymce.html.Node('em', 1));212	node3.replace(node2);213	ok(root.firstChild === node1, 'root.firstChild');214	ok(root.lastChild === node2, 'root.lastChild');215	ok(node2.parent === root, 'node2.parent');216	ok(!node2.next, 'node2.next');217	ok(node2.prev === node1, 'node2.prev');218});219test('replace middle child', function() {220	var root, node1, node2, node3, node4;221	expect(5);222	root = new tinymce.html.Node('#frag', 11);223	node1 = root.append(new tinymce.html.Node('b', 1));224	node2 = root.append(new tinymce.html.Node('b', 1));225	node3 = root.append(new tinymce.html.Node('b', 1));226	node4 = root.append(new tinymce.html.Node('em', 1));227	node2.replace(node4);228	ok(root.firstChild === node1, 'root.firstChild');229	ok(root.lastChild === node3, 'root.lastChild');230	ok(node4.parent === root, 'node4.parent');231	ok(node4.next === node3, 'node4.next');232	ok(node4.prev === node1, 'node4.prev');233});234test('attr', 22, function() {235	var node;236	node = new tinymce.html.Node('b', 1);237	deepEqual(node.attributes, []);238	node.attr('attr1', 'value1');239	equal(node.attr('attr1'), 'value1');240	equal(node.attr('attr2'), undefined);241	deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}]);242	deepEqual(node.attributes.map, {'attr1': 'value1'});243	node = new tinymce.html.Node('b', 1);244	deepEqual(node.attributes, []);245	node.attr('attr1', 'value1');246	node.attr('attr1', 'valueX');247	equal(node.attr('attr1'), 'valueX');248	deepEqual(node.attributes, [{name: 'attr1', value: 'valueX'}]);249	deepEqual(node.attributes.map, {'attr1': 'valueX'});250	node = new tinymce.html.Node('b', 1);251	deepEqual(node.attributes, []);252	node.attr('attr1', 'value1');253	node.attr('attr2', 'value2');254	equal(node.attr('attr1'), 'value1');255	equal(node.attr('attr2'), 'value2');256	deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}]);257	deepEqual(node.attributes.map, {'attr1': 'value1', 'attr2': 'value2'});258	node = new tinymce.html.Node('b', 1);259	deepEqual(node.attributes, []);260	node.attr('attr1', 'value1');261	node.attr('attr1', null);262	equal(node.attr('attr1'), undefined);263	deepEqual(node.attributes, []);264	deepEqual(node.attributes.map, {});265	node = new tinymce.html.Node('b', 1);266	node.attr({a:'1', b:'2'});267	deepEqual(node.attributes, [{name: 'a', value: '1'}, {name: 'b', value: '2'}]);268	deepEqual(node.attributes.map, {a:'1', b:'2'});269	node = new tinymce.html.Node('b', 1);270	node.attr(null);271	deepEqual(node.attributes, []);272	deepEqual(node.attributes.map, {});273});274test('clone', function() {275	var root, node, clone;276	expect(16);277	node = new tinymce.html.Node('#text', 3);278	node.value = 'value';279	clone = node.clone();280	equal(clone.name, '#text');281	equal(clone.type, 3);282	equal(clone.value, 'value');283	equal(clone.parent, undefined);284	equal(clone.next, undefined);285	equal(clone.prev, undefined);286	root = new tinymce.html.Node('#frag', 11);287	node = new tinymce.html.Node('#text', 3);288	node.value = 'value';289	root.append(node);290	equal(clone.name, '#text');291	equal(clone.type, 3);292	equal(clone.value, 'value');293	equal(clone.parent, undefined);294	equal(clone.next, undefined);295	equal(clone.prev, undefined);296	node = new tinymce.html.Node('b', 1);297	node.attr('id', 'id');298	node.attr('class', 'class');299	node.attr('title', 'title');300	clone = node.clone();301	equal(clone.name, 'b');302	equal(clone.type, 1);303	deepEqual(clone.attributes, [{name: 'class', value: 'class'}, {name: 'title', value: 'title'}]);304	deepEqual(clone.attributes.map, {'class': 'class', 'title': 'title'});305});306test('unwrap', function() {307	var root, node1, node2, node3;308	expect(7);309	root = new tinymce.html.Node('#frag', 11);310	node1 = root.append(new tinymce.html.Node('b', 1));311	node2 = node1.append(new tinymce.html.Node('em', 1));312	node1.unwrap();313	ok(root.firstChild === node2, 'root.firstChild');314	ok(root.lastChild === node2, 'root.lastChild');315	ok(node2.parent === root, 'node2.parent');316	root = new tinymce.html.Node('#frag', 11);317	node1 = root.append(new tinymce.html.Node('b', 1));318	node2 = node1.append(new tinymce.html.Node('em', 1));319	node3 = node1.append(new tinymce.html.Node('span', 1));320	node1.unwrap();321	ok(root.firstChild === node2, 'root.firstChild');322	ok(root.lastChild === node3, 'root.lastChild');323	ok(node2.parent === root, 'node2.parent');324	ok(node3.parent === root, 'node3.parent');325});326test('empty', function() {327	var root, node1, node2;328	expect(4);329	root = new tinymce.html.Node('#frag', 11);330	node1 = root.append(new tinymce.html.Node('b', 1));331	node2 = node1.append(new tinymce.html.Node('em', 1));332	node1.empty();333	ok(root.firstChild === node1, 'root.firstChild');334	ok(root.lastChild === node1, 'root.firstChild');335	ok(!node1.firstChild, 'node1.firstChild');336	ok(!node1.lastChild, 'node1.firstChild');337});338test('isEmpty', function() {339	var root, node1, node2;340	expect(9);341	root = new tinymce.html.Node('#frag', 11);342	node1 = root.append(new tinymce.html.Node('p', 1));343	node2 = node1.append(new tinymce.html.Node('b', 1));344	ok(root.isEmpty({img: 1}), 'Is empty 1');345	ok(node1.isEmpty({img: 1}), 'Is empty 2');346	root = new tinymce.html.Node('#frag', 11);347	node1 = root.append(new tinymce.html.Node('p', 1));348	node2 = node1.append(new tinymce.html.Node('img', 1));349	ok(!root.isEmpty({img: 1}), 'Is not empty 1');350	ok(!node1.isEmpty({img: 1}), 'Is not empty 2');351	root = new tinymce.html.Node('#frag', 11);352	node1 = root.append(new tinymce.html.Node('p', 1));353	node2 = node1.append(new tinymce.html.Node('#text', 3));354	node2.value = 'X';355	ok(!root.isEmpty({img: 1}), 'Is not empty 3');356	ok(!node1.isEmpty({img: 1}), 'Is not empty 4');357	root = new tinymce.html.Node('#frag', 11);358	node1 = root.append(new tinymce.html.Node('p', 1));359	node2 = node1.append(new tinymce.html.Node('#text', 3));360	node2.value = '';361	ok(root.isEmpty({img: 1}), 'Is empty 4');362	ok(node1.isEmpty({img: 1}), 'Is empty 5');363	root = new tinymce.html.Node('#frag', 11);364	node1 = root.append(new tinymce.html.Node('a', 1)).attr('name', 'x');365	ok(!root.isEmpty({img: 1}), 'Contains anchor with name attribute.');...

Full Screen

Full Screen

CaretBookmark.js

Source:CaretBookmark.js Github

copy

Full Screen

1ModuleLoader.require([2	'tinymce/caret/CaretBookmark',3	'tinymce/caret/CaretPosition'4], function(CaretBookmark, CaretPosition) {5	var assertCaretPosition = Utils.assertCaretPosition;6	module('tinymce.caret.CaretBookmark');7	function getRoot() {8		return document.getElementById('view');9	}10	function setupHtml(html) {11		getRoot().innerHTML = html;12	}13	function createTextPos(textNode, offset) {14		return new CaretPosition(textNode, offset);15	}16	test('create element index', function() {17		setupHtml('<b></b><i></i><b></b>');18		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[0])), 'b[0],before');19		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[1])), 'i[0],before');20		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[2])), 'b[1],before');21		equal(CaretBookmark.create(getRoot(), CaretPosition.after(getRoot().childNodes[2])), 'b[1],after');22	});23	test('create text index', function() {24		setupHtml('a<b></b>b<b></b>ccc');25		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');26		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 1)), 'text()[1],1');27		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 3)), 'text()[2],3');28	});29	test('create text index on fragmented text nodes', function() {30		setupHtml('a');31		getRoot().appendChild(document.createTextNode('b'));32		getRoot().appendChild(document.createTextNode('c'));33		getRoot().appendChild(document.createElement('b'));34		getRoot().appendChild(document.createTextNode('d'));35		getRoot().appendChild(document.createTextNode('e'));36		equal(getRoot().childNodes.length, 6);37		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');38		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[1], 0)), 'text()[0],1');39		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 0)), 'text()[0],2');40		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 0)), 'text()[1],0');41		equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[5], 0)), 'text()[1],1');42	});43	test('create br element index', function() {44		setupHtml('<p><br data-mce-bogus="1"></p><p><br></p>');45		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().firstChild.firstChild)), 'p[0]/br[0],before');46		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.firstChild)), 'p[1]/br[0],before');47	});48	test('create deep element index', function() {49		setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');50		equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('a'))), 'p[0]/span[1]/b[0],before');51		equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('b'))), 'p[0]/span[1]/b[1],before');52		equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('c'))), 'p[0]/span[1]/b[2],before');53		equal(CaretBookmark.create(getRoot(), CaretPosition.after(document.getElementById('c'))), 'p[0]/span[1]/b[2],after');54	});55	test('create deep text index', function() {56		setupHtml('<p><span>a</span><span id="x">a<b></b>b<b></b>ccc</span></p>');57		equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[0], 0)), 'p[0]/span[1]/text()[0],0');58		equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[2], 1)), 'p[0]/span[1]/text()[1],1');59		equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[4], 3)), 'p[0]/span[1]/text()[2],3');60	});61	test('create element index from bogus', function() {62		setupHtml('<b></b><span data-mce-bogus="1"><b></b><span data-mce-bogus="1"><b></b><b></b></span></span>');63		equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.lastChild.childNodes[1])), 'b[3],before');64	});65	test('resolve element index', function() {66		setupHtml('<b></b><i></i><b></b>');67		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[0],before'), CaretPosition.before(getRoot().childNodes[0]));68		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],before'), CaretPosition.before(getRoot().childNodes[2]));69		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],after'), CaretPosition.after(getRoot().childNodes[2]));70		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'i[0],before'), CaretPosition.before(getRoot().childNodes[1]));71	});72	test('resolve odd element names', function() {73		setupHtml('<h-2X>abc</h-2X>');74		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'h-2X[0]/text()[0],2'), createTextPos(getRoot().childNodes[0].firstChild, 2));75	});76	test('resolve deep element index', function() {77		setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');78		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[0],before'), CaretPosition.before(document.getElementById('a')));79		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[1],before'), CaretPosition.before(document.getElementById('b')));80		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],before'), CaretPosition.before(document.getElementById('c')));81		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],after'), CaretPosition.after(document.getElementById('c')));82	});83	test('resolve text index', function() {84		setupHtml('a<b></b>b<b></b>ccc');85		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));86		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[2], 1));87		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[2],3'), createTextPos(getRoot().childNodes[4], 3));88	});89	test('resolve text index on fragmented text nodes', function() {90		setupHtml('a');91		getRoot().appendChild(document.createTextNode('b'));92		getRoot().appendChild(document.createTextNode('c'));93		getRoot().appendChild(document.createElement('b'));94		getRoot().appendChild(document.createTextNode('d'));95		getRoot().appendChild(document.createTextNode('e'));96		equal(getRoot().childNodes.length, 6);97		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));98		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],1'), createTextPos(getRoot().childNodes[0], 1));99		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],2'), createTextPos(getRoot().childNodes[1], 1));100		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],3'), createTextPos(getRoot().childNodes[2], 1));101		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],4'), createTextPos(getRoot().childNodes[2], 1));102		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],0'), createTextPos(getRoot().childNodes[4], 0));103		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[4], 1));104		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],2'), createTextPos(getRoot().childNodes[5], 1));105	});106	test('resolve text index with to high offset', function() {107		setupHtml('abc');108		assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],10'), createTextPos(getRoot().childNodes[0], 3));109	});110	test('resolve invalid paths', function() {111		setupHtml('<b><i></i></b>');112		equal(CaretBookmark.resolve(getRoot(), 'x[0]/y[1]/z[2]'), null);113		equal(CaretBookmark.resolve(getRoot(), 'b[0]/i[2]'), null);114		equal(CaretBookmark.resolve(getRoot(), 'x'), null);115		equal(CaretBookmark.resolve(getRoot(), null), null);116	});...

Full Screen

Full Screen

rootattributeoperation.js

Source:rootattributeoperation.js Github

copy

Full Screen

1/**2 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license4 */5import Model from '../../../src/model/model';6import DocumentFragment from '../../../src/model/documentfragment';7import Element from '../../../src/model/element';8import RootAttributeOperation from '../../../src/model/operation/rootattributeoperation';9import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';10describe( 'RootAttributeOperation', () => {11	let model, doc, root;12	beforeEach( () => {13		model = new Model();14		doc = model.document;15		root = doc.createRoot();16	} );17	describe( 'type', () => {18		it( 'should be addRootAttribute for adding attribute', () => {19			const op = new RootAttributeOperation(20				root,21				'key',22				null,23				'newValue',24				doc.version25			);26			expect( op.type ).to.equal( 'addRootAttribute' );27		} );28		it( 'should be removeRootAttribute for removing attribute', () => {29			const op = new RootAttributeOperation(30				root,31				'key',32				'oldValue',33				null,34				doc.version35			);36			expect( op.type ).to.equal( 'removeRootAttribute' );37		} );38		it( 'should be changeRootAttribute for removing attribute', () => {39			const op = new RootAttributeOperation(40				root,41				'key',42				'oldValue',43				'newValue',44				doc.version45			);46			expect( op.type ).to.equal( 'changeRootAttribute' );47		} );48	} );49	it( 'should add attribute on the root element', () => {50		model.applyOperation(51			new RootAttributeOperation(52				root,53				'isNew',54				null,55				true,56				doc.version57			)58		);59		expect( doc.version ).to.equal( 1 );60		expect( root.hasAttribute( 'isNew' ) ).to.be.true;61	} );62	it( 'should change attribute on the root element', () => {63		root._setAttribute( 'isNew', false );64		model.applyOperation(65			new RootAttributeOperation(66				root,67				'isNew',68				false,69				true,70				doc.version71			)72		);73		expect( doc.version ).to.equal( 1 );74		expect( root.getAttribute( 'isNew' ) ).to.be.true;75	} );76	it( 'should remove attribute from the root element', () => {77		root._setAttribute( 'x', true );78		model.applyOperation(79			new RootAttributeOperation(80				root,81				'x',82				true,83				null,84				doc.version85			)86		);87		expect( doc.version ).to.equal( 1 );88		expect( root.hasAttribute( 'x' ) ).to.be.false;89	} );90	it( 'should create a RootAttributeOperation as a reverse', () => {91		const operation = new RootAttributeOperation( root, 'x', 'old', 'new', doc.version );92		const reverse = operation.getReversed();93		expect( reverse ).to.be.an.instanceof( RootAttributeOperation );94		expect( reverse.baseVersion ).to.equal( 1 );95		expect( reverse.root ).to.equal( root );96		expect( reverse.key ).to.equal( 'x' );97		expect( reverse.oldValue ).to.equal( 'new' );98		expect( reverse.newValue ).to.equal( 'old' );99	} );100	it( 'should undo adding attribute by applying reverse operation', () => {101		const operation = new RootAttributeOperation(102			root,103			'isNew',104			null,105			true,106			doc.version107		);108		const reverse = operation.getReversed();109		model.applyOperation( operation );110		model.applyOperation( reverse );111		expect( doc.version ).to.equal( 2 );112		expect( root.hasAttribute( 'x' ) ).to.be.false;113	} );114	it( 'should undo changing attribute by applying reverse operation', () => {115		root._setAttribute( 'isNew', false );116		const operation = new RootAttributeOperation(117			root,118			'isNew',119			false,120			true,121			doc.version122		);123		const reverse = operation.getReversed();124		model.applyOperation( operation );125		model.applyOperation( reverse );126		expect( doc.version ).to.equal( 2 );127		expect( root.getAttribute( 'isNew' ) ).to.be.false;128	} );129	it( 'should undo remove attribute by applying reverse operation', () => {130		root._setAttribute( 'foo', true );131		const operation = new RootAttributeOperation(132			root,133			'foo',134			true,135			null,136			doc.version137		);138		const reverse = operation.getReversed();139		model.applyOperation( operation );140		model.applyOperation( reverse );141		expect( doc.version ).to.equal( 2 );142		expect( root.getAttribute( 'foo' ) ).to.be.true;143	} );144	describe( '_validate()', () => {145		it( 'should throw an error when trying to change non-root element', () => {146			const child = new Element( 'p' );147			const parent = new Element( 'p' );148			parent._appendChild( child );149			expectToThrowCKEditorError( () => {150				const op = new RootAttributeOperation(151					child,152					'foo',153					null,154					'bar',155					null156				);157				op._validate();158			}, /rootattribute-operation-not-a-root/ );159		} );160		it( 'should throw an error when trying to change document fragment', () => {161			expectToThrowCKEditorError( () => {162				const op = new RootAttributeOperation(163					new DocumentFragment(),164					'foo',165					null,166					'bar',167					null168				);169				op._validate();170			}, /rootattribute-operation-not-a-root/ );171		} );172		it( 'should throw an error when trying to remove an attribute that does not exists', () => {173			expectToThrowCKEditorError( () => {174				const op = new RootAttributeOperation(175					root,176					'foo',177					true,178					null,179					doc.version180				);181				op._validate();182			}, /rootattribute-operation-wrong-old-value/, model );183		} );184		it( 'should throw an error when trying to add an attribute that already exists', () => {185			root._setAttribute( 'x', 1 );186			expectToThrowCKEditorError( () => {187				const op = new RootAttributeOperation(188					root,189					'x',190					null,191					2,192					doc.version193				);194				op._validate();195			}, /rootattribute-operation-attribute-exists/, model );196		} );197	} );198	it( 'should create a RootAttributeOperation with the same parameters when cloned', () => {199		const baseVersion = doc.version;200		const op = new RootAttributeOperation( root, 'foo', 'old', 'new', baseVersion );201		const clone = op.clone();202		// New instance rather than a pointer to the old instance.203		expect( clone ).not.to.equal( op );204		expect( clone ).to.be.instanceof( RootAttributeOperation );205		expect( clone.root ).to.equal( root );206		expect( clone.key ).to.equal( 'foo' );207		expect( clone.oldValue ).to.equal( 'old' );208		expect( clone.newValue ).to.equal( 'new' );209		expect( clone.baseVersion ).to.equal( baseVersion );210	} );211	describe( 'toJSON', () => {212		it( 'should create proper serialized object', () => {213			const op = new RootAttributeOperation(214				root,215				'key',216				null,217				'newValue',218				doc.version219			);220			const serialized = op.toJSON();221			expect( serialized.__className ).to.equal( 'RootAttributeOperation' );222			expect( serialized ).to.deep.equal( {223				__className: 'RootAttributeOperation',224				baseVersion: 0,225				key: 'key',226				newValue: 'newValue',227				oldValue: null,228				root: 'main'229			} );230		} );231	} );232	describe( 'fromJSON', () => {233		it( 'should create proper RootAttributeOperation from json object', () => {234			const op = new RootAttributeOperation( root, 'key', null, 'newValue', doc.version );235			const serialized = op.toJSON();236			const deserialized = RootAttributeOperation.fromJSON( serialized, doc );237			expect( deserialized ).to.deep.equal( op );238		} );239		it( 'should throw an error when root does not exists', () => {240			const op = new RootAttributeOperation(241				root,242				'key',243				null,244				'newValue',245				doc.version246			);247			const serialized = op.toJSON();248			serialized.root = 'no-root';249			expectToThrowCKEditorError( () => {250				RootAttributeOperation.fromJSON( serialized, doc );251			}, /rootattribute-operation-fromjson-no-root/ );252		} );253	} );...

Full Screen

Full Screen

api.js

Source:api.js Github

copy

Full Screen

1// 以下是业务服务器API地址2// 本机开发时使用3 var WxApiRoot = 'http://localhost:8080/wx/';4// 局域网测试使用5// var WxApiRoot = 'http://192.168.0.101:8080/wx/';6// 云平台部署时使用7// var WxApiRoot = 'http://122.152.206.172:8080/wx/';8// 云平台上线时使用9// var WxApiRoot = 'https://www.menethil.com.cn/wx/';10module.exports = {11 IndexUrl: WxApiRoot + 'home/index', //首页数据接口12 CatalogList: WxApiRoot + 'catalog/index', //分类目录全部分类数据接口13 CatalogCurrent: WxApiRoot + 'catalog/current', //分类目录当前分类数据接口14 AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录15 AuthLoginByAccount: WxApiRoot + 'auth/login', //账号登录16 AuthRegister: WxApiRoot + 'auth/register', //账号注册17 AuthReset: WxApiRoot + 'auth/reset', //账号密码重置18 AuthRegisterCaptcha: WxApiRoot + 'auth/regCaptcha', //验证码19 AuthBindPhone: WxApiRoot + 'auth/bindPhone', //绑定微信手机号20 GoodsCount: WxApiRoot + 'goods/count', //统计商品总数21 GoodsList: WxApiRoot + 'goods/list', //获得商品列表22 GoodsCategory: WxApiRoot + 'goods/category', //获得分类数据23 GoodsDetail: WxApiRoot + 'goods/detail', //获得商品的详情24 GoodsNew: WxApiRoot + 'goods/new', //新品25 GoodsHot: WxApiRoot + 'goods/hot', //热门26 GoodsRelated: WxApiRoot + 'goods/related', //商品详情页的关联商品(大家都在看)27 BrandList: WxApiRoot + 'brand/list', //品牌列表28 BrandDetail: WxApiRoot + 'brand/detail', //品牌详情29 CartList: WxApiRoot + 'cart/index', //获取购物车的数据30 CartAdd: WxApiRoot + 'cart/add', // 添加商品到购物车31 CartFastAdd: WxApiRoot + 'cart/fastadd', // 立即购买商品32 CartUpdate: WxApiRoot + 'cart/update', // 更新购物车的商品33 CartDelete: WxApiRoot + 'cart/delete', // 删除购物车的商品34 CartChecked: WxApiRoot + 'cart/checked', // 选择或取消选择商品35 CartGoodsCount: WxApiRoot + 'cart/goodscount', // 获取购物车商品件数36 CartCheckout: WxApiRoot + 'cart/checkout', // 下单前信息确认37 CollectList: WxApiRoot + 'collect/list', //收藏列表38 CollectAddOrDelete: WxApiRoot + 'collect/addordelete', //添加或取消收藏39 CommentList: WxApiRoot + 'comment/list', //评论列表40 CommentCount: WxApiRoot + 'comment/count', //评论总数41 CommentPost: WxApiRoot + 'comment/post', //发表评论42 TopicList: WxApiRoot + 'topic/list', //专题列表43 TopicDetail: WxApiRoot + 'topic/detail', //专题详情44 TopicRelated: WxApiRoot + 'topic/related', //相关专题45 SearchIndex: WxApiRoot + 'search/index', //搜索关键字46 SearchResult: WxApiRoot + 'search/result', //搜索结果47 SearchHelper: WxApiRoot + 'search/helper', //搜索帮助48 SearchClearHistory: WxApiRoot + 'search/clearhistory', //搜索历史清楚49 AddressList: WxApiRoot + 'address/list', //收货地址列表50 AddressDetail: WxApiRoot + 'address/detail', //收货地址详情51 AddressSave: WxApiRoot + 'address/save', //保存收货地址52 AddressDelete: WxApiRoot + 'address/delete', //保存收货地址53 ExpressQuery: WxApiRoot + 'express/query', //物流查询54 RegionList: WxApiRoot + 'region/list', //获取区域列表55 OrderSubmit: WxApiRoot + 'order/submit', // 提交订单56 OrderPrepay: WxApiRoot + 'order/prepay', // 订单的预支付会话57 OrderList: WxApiRoot + 'order/list', //订单列表58 OrderDetail: WxApiRoot + 'order/detail', //订单详情59 OrderCancel: WxApiRoot + 'order/cancel', //取消订单60 OrderRefund: WxApiRoot + 'order/refund', //退款取消订单61 OrderDelete: WxApiRoot + 'order/delete', //删除订单62 OrderConfirm: WxApiRoot + 'order/confirm', //确认收货63 OrderComment: WxApiRoot + 'order/comment', // 代评价商品信息64 FootprintList: WxApiRoot + 'footprint/list', //足迹列表65 FootprintDelete: WxApiRoot + 'footprint/delete', //删除足迹66 UserFormIdCreate: WxApiRoot + 'formid/create', //用户FromId,用于发送模版消息67 GroupOn: WxApiRoot + 'groupon/query', //团购API-查询68 GroupOnMy: WxApiRoot + 'groupon/my', //团购API-我的团购69 GroupOnDetail: WxApiRoot + 'groupon/detail', //团购API-详情70 GroupOnJoin: WxApiRoot + 'groupon/join', //团购API-详情71  StorageUpload: WxApiRoot + 'storage/upload' //图片上传...

Full Screen

Full Screen

binaryTree.js

Source:binaryTree.js Github

copy

Full Screen

1'use strict';2class Node {3  constructor(value) {4    this.value = value;5    this.left = null;6    this.right = null;7  }8}9class BinaryTree {10  constructor() {11    this.root = null;12  }13  preOrder() {14    let resultArr = [];15    let _preOrder = (root) => {16      if (root !== null) {17        resultArr.push(root.value);18        if (root.left !== null) {19          _preOrder(root.left);20        }21        if (root.right !== null) {22          _preOrder(root.right);23        }24      }25    };26    _preOrder(this.root);27    return resultArr;28  }29  inOrder() {30    let resultArr = [];31    let _inOrder = (root) => {32      if (root !== null) {33        if (root.left !== null) {34          _inOrder(root.left);35        }36        resultArr.push(root.value);37        if (root.right !== null) {38          _inOrder(root.right);39        }40      }41    };42    _inOrder(this.root);43    return resultArr;44  }45  postOrder() {46    let resultArr = [];47    let _postOrder = (root) => {48      if (root !== null) {49        if (root.left !== null) {50          _postOrder(root.left);51        }52        if (root.right !== null) {53          _postOrder(root.right);54        }55        resultArr.push(root.value);56      }57    };58    _postOrder(this.root);59    return resultArr;60  }61  addBinarySearch(value) {62    let _add = (inputValue, root) => {63      if (root === null) {64        root = new Node(inputValue);65      }66      else if (root.value === inputValue) {67        throw `Binary Search Tree already contains ${inputValue}. Nothing was added to the tree`;68      }69      else if (inputValue < root.value) {70        root.left = _add(inputValue, root.left);71      }72      else if (inputValue > root.value) {73        root.right = _add(inputValue, root.right);74      }75      return root;76    };77    try {78      this.root = _add(value, this.root);79    } catch (error) {80      console.log(error);81    }82  }83  findMax() {84    if (this.root === null) {85      throw 'Error: Binary Tree is empty';86    }87    else {88      let max = null;89      let _preOrderMax = (root, maxValue) => {90        if (root !== null) {91          if (root.value > maxValue) {92            maxValue = root.value;93          }94          if (root.left !== null) {95            maxValue = _preOrderMax(root.left, maxValue);96          }97          if (root.right !== null) {98            maxValue = _preOrderMax(root.right, maxValue);99          }100        }101        return maxValue;102      };103      max = this.root.value;104      return _preOrderMax(this.root, max);105    }106  }107}...

Full Screen

Full Screen

rootelement.js

Source:rootelement.js Github

copy

Full Screen

1/**2 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license4 */5import Model from '../../src/model/model';6import Element from '../../src/model/element';7import RootElement from '../../src/model/rootelement';8import count from '@ckeditor/ckeditor5-utils/src/count';9describe( 'RootElement', () => {10	describe( 'constructor()', () => {11		it( 'should create root element without attributes', () => {12			const model = new Model();13			const doc = model.document;14			const root = new RootElement( doc );15			expect( root ).to.be.an.instanceof( Element );16			expect( root ).to.have.property( 'document' ).that.equals( doc );17			expect( count( root.getAttributes() ) ).to.equal( 0 );18			expect( root.childCount ).to.equal( 0 );19		} );20	} );21	describe( 'is()', () => {22		let root;23		before( () => {24			const model = new Model();25			const doc = model.document;26			root = new RootElement( doc, '$root' );27		} );28		it( 'should return true for rootElement, element, element with same name and element name', () => {29			expect( root.is( 'element', '$root' ) ).to.be.true;30			expect( root.is( 'model:element', '$root' ) ).to.be.true;31			expect( root.is( 'element' ) ).to.be.true;32			expect( root.is( 'model:element' ) ).to.be.true;33			expect( root.is( 'rootElement', '$root' ) ).to.be.true;34			expect( root.is( 'model:rootElement', '$root' ) ).to.be.true;35			expect( root.is( 'rootElement' ) ).to.be.true;36			expect( root.is( 'model:rootElement' ) ).to.be.true;37			expect( root.is( 'node' ) ).to.be.true;38			expect( root.is( 'model:node' ) ).to.be.true;39		} );40		it( 'should return false for other accept values', () => {41			expect( root.is( 'element', '$graveyard' ) ).to.be.false;42			expect( root.is( 'model:element', '$graveyard' ) ).to.be.false;43			expect( root.is( 'rootElement', '$graveyard' ) ).to.be.false;44			expect( root.is( 'model:rootElement', '$graveyard' ) ).to.be.false;45			expect( root.is( '$graveyard' ) ).to.be.false;46			expect( root.is( '$text' ) ).to.be.false;47			expect( root.is( '$textProxy' ) ).to.be.false;48			expect( root.is( 'documentFragment' ) ).to.be.false;49			expect( root.is( 'view:element' ) ).to.be.false;50			expect( root.is( '$root' ) ).to.be.false;51			expect( root.is( 'model:$root' ) ).to.be.false;52			expect( root.is( 'node', '$root' ) ).to.be.false;53			expect( root.is( 'model:node', '$root' ) ).to.be.false;54		} );55	} );...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My first test suite', function() {2    it('My first test case', function() {3        cy.get('.search-keyword').type('ca')4        cy.wait(2000)5        cy.get('.products').as('productLocator')6        cy.get('@productLocator').find('.product').should('have.length',5)7        cy.get('@productLocator').find('.product').eq(2).contains('ADD TO CART').click().then(function()8        {9            console.log('sf')10        })11        cy.get('@productLocator').find('.product').each(($el, index, $list) => {12            const textVeg=$el.find('h4.product-name').text()13            if(textVeg.includes('Cashews'))14            {15                $el.find('button').click()16            }17        })18        cy.get('.brand').should('have.text','GREENKART')19        cy.get('.brand').then(function(logoelement){20            cy.log(logoelement.text())21        })22        cy.get('.brand').then(function(logoelement){23            cy.log(logoelement.text())24        })25        cy.get('.brand').then(function(logoelement){26            cy.log(logoelement.text())27        })28        cy.get('.brand').then(function(logoelement){29            cy.log(logoelement.text())30        })31        cy.get('.brand').then(function(logoelement){32            cy.log(logoelement.text())33        })34        cy.get('.brand').then(function(logoelement){35            cy.log(logoelement.text())36        })37        cy.get('.brand').then(function(logoelement){38            cy.log(logoelement.text())39        })40        cy.get('.brand').then(function(logoelement){41            cy.log(logoelement.text())42        })43        cy.get('.brand').then(function(logoelement){44            cy.log(logoelement.text())45        })46        cy.get('.brand').then(function(logoelement){47            cy.log(logoelement.text())48        })49    })50})

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2    it('Does not do much!', function() {3      cy.contains('type').click()4      cy.url().should('include', '/commands/actions')5      cy.get('.action-email')6        .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', () => {2  it('Does not do much!', () => {3    expect(true).to.equal(true)4  })5})6describe('My First Test', () => {7  it('Does not do much!', () => {8    cy.contains('type').click()9    cy.url().should('include', '/commands/actions')10  })11})12describe('My First Test', () => {13  it('Does not do much!', () => {14    cy.contains('type').click()15    cy.url().should('include', '/commands/actions')16  })17})18describe('My First Test', () => {19  it('Does not do much!', () => {20    cy.contains('type').click()21    cy.url().should('include', '/commands/actions')22  })23})24describe('My First Test', () => {25  it('Does not do much!', () => {26    cy.contains('type').click()27    cy.url().should('include', '/commands/actions')28  })29})30describe('My First Test', () => {31  it('Does not do much!', () => {32    cy.contains('type').click()33    cy.url().should('include', '/commands/actions')34  })35})36describe('My First Test', () => {37  it('Does not do much!', () => {38    cy.contains('type').click()39    cy.url().should('include', '/commands/actions')40  })41})42describe('My First Test', () => {43  it('Does not do much!', () => {44    cy.contains('type').click()45    cy.url().should('include', '/commands/actions')46  })47})48describe('My First Test', () => {49  it('Does not do much!', ()

Full Screen

Using AI Code Generation

copy

Full Screen

1describe("My First Test", () => {2  it("Visits the Kitchen Sink", () => {3  });4});5describe("My First Test", () => {6  it("Visits the Kitchen Sink", () => {7    cy.contains("type");8  });9});10describe("My First Test", () => {11  it("Visits the Kitchen Sink", () => {12    cy.contains("type").click();13  });14});15describe("My First Test", () => {16  it("Visits the Kitchen Sink", () => {17    cy.contains("type").click();18    cy.url().should("include", "/commands/actions");19  });20});21describe("My First Test", () => {22  it("Visits the Kitchen Sink", () => {23    cy.contains("type").click();24    cy.url().should("include", "/commands/actions");25    cy.get(".action-email")26      .type("

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', () => {2  it('Visits the Kitchen Sink', () => {3  })4})5describe('My First Test', () => {6  it('Visits the Kitchen Sink', () => {7  })8})9describe('My First Test', () => {10  it('Visits the Kitchen Sink', () => {11  })12})13describe('My First Test', () => {14  it('Visits the Kitchen Sink', () => {15  })16})17describe('My First Test', () => {18  it('Visits the Kitchen Sink', () => {19  })20})21describe('My First Test', () => {22  it('Visits the Kitchen Sink', () => {23  })24})25describe('My First Test', () => {26  it('Visits the Kitchen Sink', () => {27  })28})29describe('My First Test', () => {30  it('Visits the Kitchen Sink', () => {31  })32})33describe('My First Test', () => {34  it('Visits the Kitchen Sink', () => {35  })36})

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test Suite', function() 2{3    it('My FirstTest case', function() {4        cy.get('.search-keyword').type('ca')5        cy.wait(2000)6        cy.get('.products').as('productLocator')7        cy.get('@productLocator').find('.product').should('have.length',5)8        cy.get(':nth-child(3) > .product-action > button').click()9        cy.get('@productLocator').find('.product').should('have.length',4)10        cy.get('@productLocator').contains('ADD TO CART').click().should('have.length',4)11        cy.get('@productLocator').find('.product').eq(2).contains('ADD TO CART').click()12        cy.get('.brand').should('have.text','GREENKART')13        cy.get('.brand').then(function(logoelement){14            cy.log(logoelement.text())15        })16        cy.get('.brand').then(function(logoelement){17            cy.log(logoelement.text())18        })19        cy.get('.brand').then(function(logoelement){20            cy.log(logoelement.text())21        })22        cy.get('.brand').then(function(logoelement){23            cy.log(logoelement.text())24        })25        cy.get('.brand').then(function(logoelement){

Full Screen

Using AI Code Generation

copy

Full Screen

1it('should navigate to the homepage', () => {2    cy.visit('/')3})4it('should navigate to the homepage', () => {5    cy.visit('/')6    cy.contains('h1', 'Welcome to our store')7})8it('should navigate to the homepage', () => {9    cy.visit('/')10    cy.contains('h1', 'Welcome to our store')11    cy.get('nav a').should('have.length', 3)12})13it('should navigate to the homepage', () => {14    cy.visit('/')15    cy.contains('h1', 'Welcome to our store')16    cy.get('nav a').should('have.length', 3)17    cy.get('nav a').eq(1).click()18    cy.contains('h2', 'Products')19})20it('should navigate to the homepage', () => {21    cy.visit('/')22    cy.contains('h1', 'Welcome to our store')23    cy.get('nav a').should('have.length', 3)24    cy.get('nav a').eq(1).click()25    cy.contains('h2', 'Products')26    cy.get('nav a').eq(2).click()27    cy.contains('h2', 'Cart')28})29it('should navigate to the homepage', () => {30    cy.visit('/')31    cy.contains('h1', 'Welcome to our store')32    cy.get('nav a').should('have.length', 3)33    cy.get('nav a').eq(1).click()34    cy.contains('h2', 'Products')35    cy.get('nav a').eq(2).click()36    cy.contains('h2', 'Cart')37    cy.get('nav a').eq(0).click()38    cy.contains('h1', 'Welcome to our store')39})40it('should navigate to the homepage', () => {41    cy.visit('/')42    cy.contains('h1', 'Welcome to our store')43    cy.get('nav a').should('have.length', 3)44    cy.get('nav a').eq(1).click()45    cy.contains('h2', 'Products')46    cy.get('nav a').eq(2).click()47    cy.contains('h2', 'Cart')

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('Root', () => {2  it('works', () => {3    cy.visit('/')4  })5})6describe('Homepage', () => {7  it('has a title', () => {8    cy.visit('/')9    cy.get('h1').contains('Home')10  })11})12describe('About page', () => {13  it('has a title', () => {14    cy.visit('/about')15    cy.get('h1').contains('About')16  })17})18describe('Contact page', () => {19  it('has a title', () => {20    cy.visit('/contact')21    cy.get('h1').contains('Contact')22  })23})24describe('Contact page', () => {25  it('has a title', () => {26    cy.visit('/contact')27    cy.get('h1').contains('Contact')28  })29})30![Test Results](

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful