How to use useMutableSource method in Playwright Internal

Best JavaScript code snippet using playwright-internal

useMutableSource-test.internal.js

Source:useMutableSource-test.internal.js Github

copy

Full Screen

...116 function createMutableSource(source) {117 return React.createMutableSource(source, param => param.version);118 }119 function Component({getSnapshot, label, mutableSource, subscribe}) {120 const snapshot = useMutableSource(mutableSource, getSnapshot, subscribe);121 Scheduler.unstable_yieldValue(`${label}:${snapshot}`);122 return <div>{`${label}:${snapshot}`}</div>;123 }124 beforeEach(loadModules);125 // @gate experimental126 it('should subscribe to a source and schedule updates when it changes', () => {127 const source = createSource('one');128 const mutableSource = createMutableSource(source);129 act(() => {130 ReactNoop.renderToRootWithID(131 <>132 <Component133 label="a"134 getSnapshot={defaultGetSnapshot}135 mutableSource={mutableSource}136 subscribe={defaultSubscribe}137 />138 <Component139 label="b"140 getSnapshot={defaultGetSnapshot}141 mutableSource={mutableSource}142 subscribe={defaultSubscribe}143 />144 </>,145 'root',146 () => Scheduler.unstable_yieldValue('Sync effect'),147 );148 expect(Scheduler).toFlushAndYieldThrough([149 'a:one',150 'b:one',151 'Sync effect',152 ]);153 // Subscriptions should be passive154 expect(source.listenerCount).toBe(0);155 ReactNoop.flushPassiveEffects();156 expect(source.listenerCount).toBe(2);157 // Changing values should schedule an update with React158 source.value = 'two';159 expect(Scheduler).toFlushAndYieldThrough(['a:two', 'b:two']);160 // Umounting a component should remove its subscriptino.161 ReactNoop.renderToRootWithID(162 <>163 <Component164 label="a"165 getSnapshot={defaultGetSnapshot}166 mutableSource={mutableSource}167 subscribe={defaultSubscribe}168 />169 </>,170 'root',171 () => Scheduler.unstable_yieldValue('Sync effect'),172 );173 expect(Scheduler).toFlushAndYield(['a:two', 'Sync effect']);174 ReactNoop.flushPassiveEffects();175 expect(source.listenerCount).toBe(1);176 // Umounting a root should remove the remaining event listeners177 ReactNoop.unmountRootWithID('root');178 expect(Scheduler).toFlushAndYield([]);179 ReactNoop.flushPassiveEffects();180 expect(source.listenerCount).toBe(0);181 // Changes to source should not trigger an updates or warnings.182 source.value = 'three';183 expect(Scheduler).toFlushAndYield([]);184 });185 });186 // @gate experimental187 it('should restart work if a new source is mutated during render', () => {188 const source = createSource('one');189 const mutableSource = createMutableSource(source);190 act(() => {191 ReactNoop.render(192 <>193 <Component194 label="a"195 getSnapshot={defaultGetSnapshot}196 mutableSource={mutableSource}197 subscribe={defaultSubscribe}198 />199 <Component200 label="b"201 getSnapshot={defaultGetSnapshot}202 mutableSource={mutableSource}203 subscribe={defaultSubscribe}204 />205 </>,206 () => Scheduler.unstable_yieldValue('Sync effect'),207 );208 // Do enough work to read from one component209 expect(Scheduler).toFlushAndYieldThrough(['a:one']);210 // Mutate source before continuing work211 source.value = 'two';212 // Render work should restart and the updated value should be used213 expect(Scheduler).toFlushAndYield(['a:two', 'b:two', 'Sync effect']);214 });215 });216 // @gate experimental217 it('should schedule an update if a new source is mutated between render and commit (subscription)', () => {218 const source = createSource('one');219 const mutableSource = createMutableSource(source);220 act(() => {221 ReactNoop.render(222 <>223 <Component224 label="a"225 getSnapshot={defaultGetSnapshot}226 mutableSource={mutableSource}227 subscribe={defaultSubscribe}228 />229 <Component230 label="b"231 getSnapshot={defaultGetSnapshot}232 mutableSource={mutableSource}233 subscribe={defaultSubscribe}234 />235 </>,236 () => Scheduler.unstable_yieldValue('Sync effect'),237 );238 // Finish rendering239 expect(Scheduler).toFlushAndYieldThrough([240 'a:one',241 'b:one',242 'Sync effect',243 ]);244 // Mutate source before subscriptions are attached245 expect(source.listenerCount).toBe(0);246 source.value = 'two';247 // Mutation should be detected, and a new render should be scheduled248 expect(Scheduler).toFlushAndYield(['a:two', 'b:two']);249 });250 });251 // @gate experimental252 it('should unsubscribe and resubscribe if a new source is used', () => {253 const sourceA = createSource('a-one');254 const mutableSourceA = createMutableSource(sourceA);255 const sourceB = createSource('b-one');256 const mutableSourceB = createMutableSource(sourceB);257 act(() => {258 ReactNoop.render(259 <Component260 label="only"261 getSnapshot={defaultGetSnapshot}262 mutableSource={mutableSourceA}263 subscribe={defaultSubscribe}264 />,265 () => Scheduler.unstable_yieldValue('Sync effect'),266 );267 expect(Scheduler).toFlushAndYield(['only:a-one', 'Sync effect']);268 ReactNoop.flushPassiveEffects();269 expect(sourceA.listenerCount).toBe(1);270 // Changing values should schedule an update with React271 sourceA.value = 'a-two';272 expect(Scheduler).toFlushAndYield(['only:a-two']);273 // If we re-render with a new source, the old one should be unsubscribed.274 ReactNoop.render(275 <Component276 label="only"277 getSnapshot={defaultGetSnapshot}278 mutableSource={mutableSourceB}279 subscribe={defaultSubscribe}280 />,281 () => Scheduler.unstable_yieldValue('Sync effect'),282 );283 expect(Scheduler).toFlushAndYield(['only:b-one', 'Sync effect']);284 ReactNoop.flushPassiveEffects();285 expect(sourceA.listenerCount).toBe(0);286 expect(sourceB.listenerCount).toBe(1);287 // Changing to original source should not schedule updates with React288 sourceA.value = 'a-three';289 expect(Scheduler).toFlushAndYield([]);290 // Changing new source value should schedule an update with React291 sourceB.value = 'b-two';292 expect(Scheduler).toFlushAndYield(['only:b-two']);293 });294 });295 // @gate experimental296 it('should unsubscribe and resubscribe if a new subscribe function is provided', () => {297 const source = createSource('a-one');298 const mutableSource = createMutableSource(source);299 const unsubscribeA = jest.fn();300 const subscribeA = jest.fn(s => {301 const unsubscribe = defaultSubscribe(s);302 return () => {303 unsubscribe();304 unsubscribeA();305 };306 });307 const unsubscribeB = jest.fn();308 const subscribeB = jest.fn(s => {309 const unsubscribe = defaultSubscribe(s);310 return () => {311 unsubscribe();312 unsubscribeB();313 };314 });315 act(() => {316 ReactNoop.renderToRootWithID(317 <Component318 label="only"319 getSnapshot={defaultGetSnapshot}320 mutableSource={mutableSource}321 subscribe={subscribeA}322 />,323 'root',324 () => Scheduler.unstable_yieldValue('Sync effect'),325 );326 expect(Scheduler).toFlushAndYield(['only:a-one', 'Sync effect']);327 ReactNoop.flushPassiveEffects();328 expect(source.listenerCount).toBe(1);329 expect(subscribeA).toHaveBeenCalledTimes(1);330 // If we re-render with a new subscription function,331 // the old unsubscribe function should be called.332 ReactNoop.renderToRootWithID(333 <Component334 label="only"335 getSnapshot={defaultGetSnapshot}336 mutableSource={mutableSource}337 subscribe={subscribeB}338 />,339 'root',340 () => Scheduler.unstable_yieldValue('Sync effect'),341 );342 expect(Scheduler).toFlushAndYield(['only:a-one', 'Sync effect']);343 ReactNoop.flushPassiveEffects();344 expect(source.listenerCount).toBe(1);345 expect(unsubscribeA).toHaveBeenCalledTimes(1);346 expect(subscribeB).toHaveBeenCalledTimes(1);347 // Unmounting should call the newer unsunscribe.348 ReactNoop.unmountRootWithID('root');349 expect(Scheduler).toFlushAndYield([]);350 ReactNoop.flushPassiveEffects();351 expect(source.listenerCount).toBe(0);352 expect(unsubscribeB).toHaveBeenCalledTimes(1);353 });354 });355 // @gate experimental356 it('should re-use previously read snapshot value when reading is unsafe', () => {357 const source = createSource('one');358 const mutableSource = createMutableSource(source);359 act(() => {360 ReactNoop.render(361 <>362 <Component363 label="a"364 getSnapshot={defaultGetSnapshot}365 mutableSource={mutableSource}366 subscribe={defaultSubscribe}367 />368 <Component369 label="b"370 getSnapshot={defaultGetSnapshot}371 mutableSource={mutableSource}372 subscribe={defaultSubscribe}373 />374 </>,375 () => Scheduler.unstable_yieldValue('Sync effect'),376 );377 expect(Scheduler).toFlushAndYield(['a:one', 'b:one', 'Sync effect']);378 // Changing values should schedule an update with React.379 // Start working on this update but don't finish it.380 source.value = 'two';381 expect(Scheduler).toFlushAndYieldThrough(['a:two']);382 // Re-renders that occur before the udpate is processed383 // should reuse snapshot so long as the config has not changed384 ReactNoop.flushSync(() => {385 ReactNoop.render(386 <>387 <Component388 label="a"389 getSnapshot={defaultGetSnapshot}390 mutableSource={mutableSource}391 subscribe={defaultSubscribe}392 />393 <Component394 label="b"395 getSnapshot={defaultGetSnapshot}396 mutableSource={mutableSource}397 subscribe={defaultSubscribe}398 />399 </>,400 () => Scheduler.unstable_yieldValue('Sync effect'),401 );402 });403 expect(Scheduler).toHaveYielded(['a:one', 'b:one', 'Sync effect']);404 expect(Scheduler).toFlushAndYield(['a:two', 'b:two']);405 });406 });407 // @gate experimental408 it('should read from source on newly mounted subtree if no pending updates are scheduled for source', () => {409 const source = createSource('one');410 const mutableSource = createMutableSource(source);411 act(() => {412 ReactNoop.render(413 <>414 <Component415 label="a"416 getSnapshot={defaultGetSnapshot}417 mutableSource={mutableSource}418 subscribe={defaultSubscribe}419 />420 </>,421 () => Scheduler.unstable_yieldValue('Sync effect'),422 );423 expect(Scheduler).toFlushAndYield(['a:one', 'Sync effect']);424 ReactNoop.render(425 <>426 <Component427 label="a"428 getSnapshot={defaultGetSnapshot}429 mutableSource={mutableSource}430 subscribe={defaultSubscribe}431 />432 <Component433 label="b"434 getSnapshot={defaultGetSnapshot}435 mutableSource={mutableSource}436 subscribe={defaultSubscribe}437 />438 </>,439 () => Scheduler.unstable_yieldValue('Sync effect'),440 );441 expect(Scheduler).toFlushAndYield(['a:one', 'b:one', 'Sync effect']);442 });443 });444 // @gate experimental445 it('should throw and restart render if source and snapshot are unavailable during an update', () => {446 const source = createSource('one');447 const mutableSource = createMutableSource(source);448 act(() => {449 ReactNoop.render(450 <>451 <Component452 label="a"453 getSnapshot={defaultGetSnapshot}454 mutableSource={mutableSource}455 subscribe={defaultSubscribe}456 />457 <Component458 label="b"459 getSnapshot={defaultGetSnapshot}460 mutableSource={mutableSource}461 subscribe={defaultSubscribe}462 />463 </>,464 () => Scheduler.unstable_yieldValue('Sync effect'),465 );466 expect(Scheduler).toFlushAndYield(['a:one', 'b:one', 'Sync effect']);467 ReactNoop.flushPassiveEffects();468 // Changing values should schedule an update with React.469 // Start working on this update but don't finish it.470 Scheduler.unstable_runWithPriority(Scheduler.unstable_LowPriority, () => {471 source.value = 'two';472 expect(Scheduler).toFlushAndYieldThrough(['a:two']);473 });474 const newGetSnapshot = s => 'new:' + defaultGetSnapshot(s);475 // Force a higher priority render with a new config.476 // This should signal that the snapshot is not safe and trigger a full re-render.477 Scheduler.unstable_runWithPriority(478 Scheduler.unstable_UserBlockingPriority,479 () => {480 ReactNoop.render(481 <>482 <Component483 label="a"484 getSnapshot={newGetSnapshot}485 mutableSource={mutableSource}486 subscribe={defaultSubscribe}487 />488 <Component489 label="b"490 getSnapshot={newGetSnapshot}491 mutableSource={mutableSource}492 subscribe={defaultSubscribe}493 />494 </>,495 () => Scheduler.unstable_yieldValue('Sync effect'),496 );497 },498 );499 expect(Scheduler).toFlushAndYieldThrough([500 'a:new:two',501 'b:new:two',502 'Sync effect',503 ]);504 });505 });506 // @gate experimental507 it('should throw and restart render if source and snapshot are unavailable during a sync update', () => {508 const source = createSource('one');509 const mutableSource = createMutableSource(source);510 act(() => {511 ReactNoop.render(512 <>513 <Component514 label="a"515 getSnapshot={defaultGetSnapshot}516 mutableSource={mutableSource}517 subscribe={defaultSubscribe}518 />519 <Component520 label="b"521 getSnapshot={defaultGetSnapshot}522 mutableSource={mutableSource}523 subscribe={defaultSubscribe}524 />525 </>,526 () => Scheduler.unstable_yieldValue('Sync effect'),527 );528 expect(Scheduler).toFlushAndYield(['a:one', 'b:one', 'Sync effect']);529 ReactNoop.flushPassiveEffects();530 // Changing values should schedule an update with React.531 // Start working on this update but don't finish it.532 Scheduler.unstable_runWithPriority(Scheduler.unstable_LowPriority, () => {533 source.value = 'two';534 expect(Scheduler).toFlushAndYieldThrough(['a:two']);535 });536 const newGetSnapshot = s => 'new:' + defaultGetSnapshot(s);537 // Force a higher priority render with a new config.538 // This should signal that the snapshot is not safe and trigger a full re-render.539 ReactNoop.flushSync(() => {540 ReactNoop.render(541 <>542 <Component543 label="a"544 getSnapshot={newGetSnapshot}545 mutableSource={mutableSource}546 subscribe={defaultSubscribe}547 />548 <Component549 label="b"550 getSnapshot={newGetSnapshot}551 mutableSource={mutableSource}552 subscribe={defaultSubscribe}553 />554 </>,555 () => Scheduler.unstable_yieldValue('Sync effect'),556 );557 });558 expect(Scheduler).toHaveYielded([559 'a:new:two',560 'b:new:two',561 'Sync effect',562 ]);563 });564 });565 // @gate experimental566 it('should only update components whose subscriptions fire', () => {567 const source = createComplexSource('a:one', 'b:one');568 const mutableSource = createMutableSource(source);569 // Subscribe to part of the store.570 const getSnapshotA = s => s.valueA;571 const subscribeA = (s, callback) => s.subscribeA(callback);572 const getSnapshotB = s => s.valueB;573 const subscribeB = (s, callback) => s.subscribeB(callback);574 act(() => {575 ReactNoop.render(576 <>577 <Component578 label="a"579 getSnapshot={getSnapshotA}580 mutableSource={mutableSource}581 subscribe={subscribeA}582 />583 <Component584 label="b"585 getSnapshot={getSnapshotB}586 mutableSource={mutableSource}587 subscribe={subscribeB}588 />589 </>,590 () => Scheduler.unstable_yieldValue('Sync effect'),591 );592 expect(Scheduler).toFlushAndYield(['a:a:one', 'b:b:one', 'Sync effect']);593 // Changes to part of the store (e.g. A) should not render other parts.594 source.valueA = 'a:two';595 expect(Scheduler).toFlushAndYield(['a:a:two']);596 source.valueB = 'b:two';597 expect(Scheduler).toFlushAndYield(['b:b:two']);598 });599 });600 // @gate experimental601 it('should detect tearing in part of the store not yet subscribed to', () => {602 const source = createComplexSource('a:one', 'b:one');603 const mutableSource = createMutableSource(source);604 // Subscribe to part of the store.605 const getSnapshotA = s => s.valueA;606 const subscribeA = (s, callback) => s.subscribeA(callback);607 const getSnapshotB = s => s.valueB;608 const subscribeB = (s, callback) => s.subscribeB(callback);609 act(() => {610 ReactNoop.render(611 <>612 <Component613 label="a"614 getSnapshot={getSnapshotA}615 mutableSource={mutableSource}616 subscribe={subscribeA}617 />618 </>,619 () => Scheduler.unstable_yieldValue('Sync effect'),620 );621 expect(Scheduler).toFlushAndYield(['a:a:one', 'Sync effect']);622 // Because the store has not chagned yet, there are no pending updates,623 // so it is considered safe to read from when we start this render.624 ReactNoop.render(625 <>626 <Component627 label="a"628 getSnapshot={getSnapshotA}629 mutableSource={mutableSource}630 subscribe={subscribeA}631 />632 <Component633 label="b"634 getSnapshot={getSnapshotB}635 mutableSource={mutableSource}636 subscribe={subscribeB}637 />638 <Component639 label="c"640 getSnapshot={getSnapshotB}641 mutableSource={mutableSource}642 subscribe={subscribeB}643 />644 </>,645 () => Scheduler.unstable_yieldValue('Sync effect'),646 );647 expect(Scheduler).toFlushAndYieldThrough(['a:a:one', 'b:b:one']);648 // Mutating the source should trigger a tear detection on the next read,649 // which should throw and re-render the entire tree.650 source.valueB = 'b:two';651 expect(Scheduler).toFlushAndYield([652 'a:a:one',653 'b:b:two',654 'c:b:two',655 'Sync effect',656 ]);657 });658 });659 // @gate experimental660 it('does not schedule an update for subscriptions that fire with an unchanged snapshot', () => {661 const MockComponent = jest.fn(Component);662 const source = createSource('one');663 const mutableSource = createMutableSource(source);664 act(() => {665 ReactNoop.render(666 <MockComponent667 label="only"668 getSnapshot={defaultGetSnapshot}669 mutableSource={mutableSource}670 subscribe={defaultSubscribe}671 />,672 () => Scheduler.unstable_yieldValue('Sync effect'),673 );674 expect(Scheduler).toFlushAndYieldThrough(['only:one', 'Sync effect']);675 ReactNoop.flushPassiveEffects();676 expect(source.listenerCount).toBe(1);677 // Notify subscribe function but don't change the value678 source.value = 'one';679 expect(Scheduler).toFlushWithoutYielding();680 });681 });682 // @gate experimental683 it('should throw and restart if getSnapshot changes between scheduled update and re-render', () => {684 const source = createSource('one');685 const mutableSource = createMutableSource(source);686 const newGetSnapshot = s => 'new:' + defaultGetSnapshot(s);687 let updateGetSnapshot;688 function WrapperWithState() {689 const tuple = React.useState(() => defaultGetSnapshot);690 updateGetSnapshot = tuple[1];691 return (692 <Component693 label="only"694 getSnapshot={tuple[0]}695 mutableSource={mutableSource}696 subscribe={defaultSubscribe}697 />698 );699 }700 act(() => {701 ReactNoop.render(<WrapperWithState />, () =>702 Scheduler.unstable_yieldValue('Sync effect'),703 );704 expect(Scheduler).toFlushAndYield(['only:one', 'Sync effect']);705 ReactNoop.flushPassiveEffects();706 // Change the source (and schedule an update).707 Scheduler.unstable_runWithPriority(Scheduler.unstable_LowPriority, () => {708 source.value = 'two';709 });710 // Schedule a higher priority update that changes getSnapshot.711 Scheduler.unstable_runWithPriority(712 Scheduler.unstable_UserBlockingPriority,713 () => {714 updateGetSnapshot(() => newGetSnapshot);715 },716 );717 expect(Scheduler).toFlushAndYield(['only:new:two']);718 });719 });720 // @gate experimental721 it('should recover from a mutation during yield when other work is scheduled', () => {722 const source = createSource('one');723 const mutableSource = createMutableSource(source);724 act(() => {725 // Start a render that uses the mutable source.726 ReactNoop.render(727 <>728 <Component729 label="a"730 getSnapshot={defaultGetSnapshot}731 mutableSource={mutableSource}732 subscribe={defaultSubscribe}733 />734 <Component735 label="b"736 getSnapshot={defaultGetSnapshot}737 mutableSource={mutableSource}738 subscribe={defaultSubscribe}739 />740 </>,741 );742 expect(Scheduler).toFlushAndYieldThrough(['a:one']);743 // Mutate source744 source.value = 'two';745 // Now render something different.746 ReactNoop.render(<div />);747 expect(Scheduler).toFlushAndYield([]);748 });749 });750 // @gate experimental751 it('should not throw if the new getSnapshot returns the same snapshot value', () => {752 const source = createSource('one');753 const mutableSource = createMutableSource(source);754 const onRenderA = jest.fn();755 const onRenderB = jest.fn();756 let updateGetSnapshot;757 function WrapperWithState() {758 const tuple = React.useState(() => defaultGetSnapshot);759 updateGetSnapshot = tuple[1];760 return (761 <Component762 label="b"763 getSnapshot={tuple[0]}764 mutableSource={mutableSource}765 subscribe={defaultSubscribe}766 />767 );768 }769 act(() => {770 ReactNoop.render(771 <>772 <React.Profiler id="a" onRender={onRenderA}>773 <Component774 label="a"775 getSnapshot={defaultGetSnapshot}776 mutableSource={mutableSource}777 subscribe={defaultSubscribe}778 />779 </React.Profiler>780 <React.Profiler id="b" onRender={onRenderB}>781 <WrapperWithState />782 </React.Profiler>783 </>,784 () => Scheduler.unstable_yieldValue('Sync effect'),785 );786 expect(Scheduler).toFlushAndYield(['a:one', 'b:one', 'Sync effect']);787 ReactNoop.flushPassiveEffects();788 expect(onRenderA).toHaveBeenCalledTimes(1);789 expect(onRenderB).toHaveBeenCalledTimes(1);790 // If B's getSnapshot function updates, but the snapshot it returns is the same,791 // only B should re-render (to update its state).792 updateGetSnapshot(() => s => defaultGetSnapshot(s));793 expect(Scheduler).toFlushAndYield(['b:one']);794 ReactNoop.flushPassiveEffects();795 expect(onRenderA).toHaveBeenCalledTimes(1);796 expect(onRenderB).toHaveBeenCalledTimes(2);797 });798 });799 // @gate experimental800 it('should not throw if getSnapshot changes but the source can be safely read from anyway', () => {801 const source = createSource('one');802 const mutableSource = createMutableSource(source);803 const newGetSnapshot = s => 'new:' + defaultGetSnapshot(s);804 let updateGetSnapshot;805 function WrapperWithState() {806 const tuple = React.useState(() => defaultGetSnapshot);807 updateGetSnapshot = tuple[1];808 return (809 <Component810 label="only"811 getSnapshot={tuple[0]}812 mutableSource={mutableSource}813 subscribe={defaultSubscribe}814 />815 );816 }817 act(() => {818 ReactNoop.render(<WrapperWithState />, () =>819 Scheduler.unstable_yieldValue('Sync effect'),820 );821 expect(Scheduler).toFlushAndYield(['only:one', 'Sync effect']);822 ReactNoop.flushPassiveEffects();823 // Change the source (and schedule an update)824 // but also change the snapshot function too.825 ReactNoop.batchedUpdates(() => {826 source.value = 'two';827 updateGetSnapshot(() => newGetSnapshot);828 });829 expect(Scheduler).toFlushAndYield(['only:new:two']);830 });831 });832 // @gate experimental833 it('should still schedule an update if an eager selector throws after a mutation', () => {834 const source = createSource({835 friends: [836 {id: 1, name: 'Foo'},837 {id: 2, name: 'Bar'},838 ],839 });840 const mutableSource = createMutableSource(source);841 function FriendsList() {842 const getSnapshot = React.useCallback(843 ({value}) => Array.from(value.friends),844 [],845 );846 const friends = useMutableSource(847 mutableSource,848 getSnapshot,849 defaultSubscribe,850 );851 return (852 <ul>853 {friends.map(friend => (854 <Friend key={friend.id} id={friend.id} />855 ))}856 </ul>857 );858 }859 function Friend({id}) {860 const getSnapshot = React.useCallback(861 ({value}) => {862 // This selector is intentionally written in a way that will throw863 // if no matching friend exists in the store.864 return value.friends.find(friend => friend.id === id).name;865 },866 [id],867 );868 const name = useMutableSource(869 mutableSource,870 getSnapshot,871 defaultSubscribe,872 );873 Scheduler.unstable_yieldValue(`${id}:${name}`);874 return <li>{name}</li>;875 }876 act(() => {877 ReactNoop.render(<FriendsList />, () =>878 Scheduler.unstable_yieldValue('Sync effect'),879 );880 expect(Scheduler).toFlushAndYield(['1:Foo', '2:Bar', 'Sync effect']);881 // This mutation will cause the "Bar" component to throw,882 // since its value will no longer be a part of the store.883 // Mutable source should still schedule an update though,884 // which should unmount "Bar" and mount "Baz".885 source.value = {886 friends: [887 {id: 1, name: 'Foo'},888 {id: 3, name: 'Baz'},889 ],890 };891 expect(Scheduler).toFlushAndYield(['1:Foo', '3:Baz']);892 });893 });894 // @gate experimental895 it('should not warn about updates that fire between unmount and passive unsubcribe', () => {896 const source = createSource('one');897 const mutableSource = createMutableSource(source);898 function Wrapper() {899 React.useLayoutEffect(() => () => {900 Scheduler.unstable_yieldValue('layout unmount');901 });902 return (903 <Component904 label="only"905 getSnapshot={defaultGetSnapshot}906 mutableSource={mutableSource}907 subscribe={defaultSubscribe}908 />909 );910 }911 act(() => {912 ReactNoop.renderToRootWithID(<Wrapper />, 'root', () =>913 Scheduler.unstable_yieldValue('Sync effect'),914 );915 expect(Scheduler).toFlushAndYield(['only:one', 'Sync effect']);916 ReactNoop.flushPassiveEffects();917 // Umounting a root should remove the remaining event listeners in a passive effect918 ReactNoop.unmountRootWithID('root');919 expect(Scheduler).toFlushAndYieldThrough(['layout unmount']);920 // Changes to source should not cause a warning,921 // even though the unsubscribe hasn't run yet (since it's a pending passive effect).922 source.value = 'two';923 expect(Scheduler).toFlushAndYield([]);924 });925 });926 // @gate experimental927 it('should support inline selectors and updates that are processed after selector change', async () => {928 const source = createSource({929 a: 'initial',930 b: 'initial',931 });932 const mutableSource = createMutableSource(source);933 const getSnapshotA = () => source.value.a;934 const getSnapshotB = () => source.value.b;935 function mutateB(newB) {936 source.value = {937 ...source.value,938 b: newB,939 };940 }941 function App({getSnapshot}) {942 const state = useMutableSource(943 mutableSource,944 getSnapshot,945 defaultSubscribe,946 );947 return state;948 }949 const root = ReactNoop.createRoot();950 await act(async () => {951 root.render(<App getSnapshot={getSnapshotA} />);952 });953 expect(root).toMatchRenderedOutput('initial');954 await act(async () => {955 mutateB('Updated B');956 root.render(<App getSnapshot={getSnapshotB} />);957 });958 expect(root).toMatchRenderedOutput('Updated B');959 await act(async () => {960 mutateB('Another update');961 });962 expect(root).toMatchRenderedOutput('Another update');963 });964 // @gate experimental965 it('should clear the update queue when getSnapshot changes with pending lower priority updates', async () => {966 const source = createSource({967 a: 'initial',968 b: 'initial',969 });970 const mutableSource = createMutableSource(source);971 const getSnapshotA = () => source.value.a;972 const getSnapshotB = () => source.value.b;973 function mutateA(newA) {974 source.value = {975 ...source.value,976 a: newA,977 };978 }979 function mutateB(newB) {980 source.value = {981 ...source.value,982 b: newB,983 };984 }985 function App({toggle}) {986 const state = useMutableSource(987 mutableSource,988 toggle ? getSnapshotB : getSnapshotA,989 defaultSubscribe,990 );991 const result = (toggle ? 'B: ' : 'A: ') + state;992 return result;993 }994 const root = ReactNoop.createRoot();995 await act(async () => {996 root.render(<App toggle={false} />);997 });998 expect(root).toMatchRenderedOutput('A: initial');999 await act(async () => {1000 ReactNoop.discreteUpdates(() => {1001 // Update both A and B to the same value1002 mutateA('Update');1003 mutateB('Update');1004 // Toggle to B in the same batch1005 root.render(<App toggle={true} />);1006 });1007 // Mutate A at lower priority. This should never be rendered, because1008 // by the time we get to the lower priority, we've already switched1009 // to B.1010 mutateA('OOPS! This mutation should be ignored');1011 });1012 expect(root).toMatchRenderedOutput('B: Update');1013 });1014 // @gate experimental1015 it('should clear the update queue when source changes with pending lower priority updates', async () => {1016 const sourceA = createSource('initial');1017 const sourceB = createSource('initial');1018 const mutableSourceA = createMutableSource(sourceA);1019 const mutableSourceB = createMutableSource(sourceB);1020 function App({toggle}) {1021 const state = useMutableSource(1022 toggle ? mutableSourceB : mutableSourceA,1023 defaultGetSnapshot,1024 defaultSubscribe,1025 );1026 const result = (toggle ? 'B: ' : 'A: ') + state;1027 return result;1028 }1029 const root = ReactNoop.createRoot();1030 await act(async () => {1031 root.render(<App toggle={false} />);1032 });1033 expect(root).toMatchRenderedOutput('A: initial');1034 await act(async () => {1035 ReactNoop.discreteUpdates(() => {1036 // Update both A and B to the same value1037 sourceA.value = 'Update';1038 sourceB.value = 'Update';1039 // Toggle to B in the same batch1040 root.render(<App toggle={true} />);1041 });1042 // Mutate A at lower priority. This should never be rendered, because1043 // by the time we get to the lower priority, we've already switched1044 // to B.1045 sourceA.value = 'OOPS! This mutation should be ignored';1046 });1047 expect(root).toMatchRenderedOutput('B: Update');1048 });1049 // @gate experimental1050 it('should always treat reading as potentially unsafe when getSnapshot changes between renders', async () => {1051 const source = createSource({1052 a: 'foo',1053 b: 'bar',1054 });1055 const mutableSource = createMutableSource(source);1056 const getSnapshotA = () => source.value.a;1057 const getSnapshotB = () => source.value.b;1058 function mutateA(newA) {1059 source.value = {1060 ...source.value,1061 a: newA,1062 };1063 }1064 function App({getSnapshotFirst, getSnapshotSecond}) {1065 const first = useMutableSource(1066 mutableSource,1067 getSnapshotFirst,1068 defaultSubscribe,1069 );1070 const second = useMutableSource(1071 mutableSource,1072 getSnapshotSecond,1073 defaultSubscribe,1074 );1075 let result = `x: ${first}, y: ${second}`;1076 if (getSnapshotFirst === getSnapshotSecond) {1077 // When both getSnapshot functions are equal,1078 // the two values must be consistent.1079 if (first !== second) {1080 result = 'Oops, tearing!';1081 }1082 }1083 React.useEffect(() => {1084 Scheduler.unstable_yieldValue(result);1085 }, [result]);1086 return result;1087 }1088 const root = ReactNoop.createRoot();1089 await act(async () => {1090 root.render(1091 <App1092 getSnapshotFirst={getSnapshotA}1093 getSnapshotSecond={getSnapshotB}1094 />,1095 );1096 });1097 // x and y start out reading from different parts of the store.1098 expect(Scheduler).toHaveYielded(['x: foo, y: bar']);1099 await act(async () => {1100 ReactNoop.discreteUpdates(() => {1101 // At high priority, toggle y so that it reads from A instead of B.1102 // Simultaneously, mutate A.1103 mutateA('baz');1104 root.render(1105 <App1106 getSnapshotFirst={getSnapshotA}1107 getSnapshotSecond={getSnapshotA}1108 />,1109 );1110 // If this update were processed before the next mutation,1111 // it would be expected to yield "baz" and "baz".1112 });1113 // At lower priority, mutate A again.1114 // This happens to match the initial value of B.1115 mutateA('bar');1116 // When this update is processed,1117 // it is expected to yield "bar" and "bar".1118 });1119 // Check that we didn't commit any inconsistent states.1120 // The actual sequence of work will be:1121 // 1. React renders the high-pri update, sees a new getSnapshot, detects the source has been further mutated, and throws1122 // 2. React re-renders with all pending updates, including the second mutation, and renders "bar" and "bar".1123 expect(Scheduler).toHaveYielded(['x: bar, y: bar']);1124 });1125 // @gate experimental1126 it('getSnapshot changes and then source is mutated in between paint and passive effect phase', async () => {1127 const source = createSource({1128 a: 'foo',1129 b: 'bar',1130 });1131 const mutableSource = createMutableSource(source);1132 function mutateB(newB) {1133 source.value = {1134 ...source.value,1135 b: newB,1136 };1137 }1138 const getSnapshotA = () => source.value.a;1139 const getSnapshotB = () => source.value.b;1140 function App({getSnapshot}) {1141 const value = useMutableSource(1142 mutableSource,1143 getSnapshot,1144 defaultSubscribe,1145 );1146 Scheduler.unstable_yieldValue('Render: ' + value);1147 React.useEffect(() => {1148 Scheduler.unstable_yieldValue('Commit: ' + value);1149 }, [value]);1150 return value;1151 }1152 const root = ReactNoop.createRoot();1153 await act(async () => {1154 root.render(<App getSnapshot={getSnapshotA} />);1155 });1156 expect(Scheduler).toHaveYielded(['Render: foo', 'Commit: foo']);1157 await act(async () => {1158 // Switch getSnapshot to read from B instead1159 root.render(<App getSnapshot={getSnapshotB} />);1160 // Render and finish the tree, but yield right after paint, before1161 // the passive effects have fired.1162 expect(Scheduler).toFlushUntilNextPaint(['Render: bar']);1163 // Then mutate B.1164 mutateB('baz');1165 });1166 expect(Scheduler).toHaveYielded([1167 // Fires the effect from the previous render1168 'Commit: bar',1169 // During that effect, it should detect that the snapshot has changed1170 // and re-render.1171 'Render: baz',1172 'Commit: baz',1173 ]);1174 expect(root).toMatchRenderedOutput('baz');1175 });1176 // @gate experimental1177 it('getSnapshot changes and then source is mutated in between paint and passive effect phase, case 2', async () => {1178 const source = createSource({1179 a: 'a0',1180 b: 'b0',1181 });1182 const mutableSource = createMutableSource(source);1183 const getSnapshotA = () => source.value.a;1184 const getSnapshotB = () => source.value.b;1185 function mutateA(newA) {1186 source.value = {1187 ...source.value,1188 a: newA,1189 };1190 }1191 function App({getSnapshotFirst, getSnapshotSecond}) {1192 const first = useMutableSource(1193 mutableSource,1194 getSnapshotFirst,1195 defaultSubscribe,1196 );1197 const second = useMutableSource(1198 mutableSource,1199 getSnapshotSecond,1200 defaultSubscribe,1201 );1202 return `first: ${first}, second: ${second}`;1203 }1204 const root = ReactNoop.createRoot();1205 await act(async () => {1206 root.render(1207 <App1208 getSnapshotFirst={getSnapshotA}1209 getSnapshotSecond={getSnapshotB}1210 />,1211 );1212 });1213 expect(root.getChildrenAsJSX()).toEqual('first: a0, second: b0');1214 await act(async () => {1215 // Switch the second getSnapshot to also read from A1216 root.render(1217 <App1218 getSnapshotFirst={getSnapshotA}1219 getSnapshotSecond={getSnapshotA}1220 />,1221 );1222 // Render and finish the tree, but yield right after paint, before1223 // the passive effects have fired.1224 expect(Scheduler).toFlushUntilNextPaint([]);1225 // Now mutate A. Both hooks should update.1226 // This is at high priority so that it doesn't get batched with default1227 // priority updates that might fire during the passive effect1228 ReactNoop.discreteUpdates(() => {1229 mutateA('a1');1230 });1231 expect(Scheduler).toFlushUntilNextPaint([]);1232 expect(root.getChildrenAsJSX()).toEqual('first: a1, second: a1');1233 });1234 expect(root.getChildrenAsJSX()).toEqual('first: a1, second: a1');1235 });1236 // @gate experimental1237 it('getSnapshot changes and then source is mutated during interleaved event', async () => {1238 const {useEffect} = React;1239 const source = createComplexSource('1', '2');1240 const mutableSource = createMutableSource(source);1241 // Subscribe to part of the store.1242 const getSnapshotA = s => s.valueA;1243 const subscribeA = (s, callback) => s.subscribeA(callback);1244 const configA = [getSnapshotA, subscribeA];1245 const getSnapshotB = s => s.valueB;1246 const subscribeB = (s, callback) => s.subscribeB(callback);1247 const configB = [getSnapshotB, subscribeB];1248 function App({parentConfig, childConfig}) {1249 const [getSnapshot, subscribe] = parentConfig;1250 const parentValue = useMutableSource(1251 mutableSource,1252 getSnapshot,1253 subscribe,1254 );1255 Scheduler.unstable_yieldValue('Parent: ' + parentValue);1256 return (1257 <Child1258 parentConfig={parentConfig}1259 childConfig={childConfig}1260 parentValue={parentValue}1261 />1262 );1263 }1264 function Child({parentConfig, childConfig, parentValue}) {1265 const [getSnapshot, subscribe] = childConfig;1266 const childValue = useMutableSource(1267 mutableSource,1268 getSnapshot,1269 subscribe,1270 );1271 Scheduler.unstable_yieldValue('Child: ' + childValue);1272 let result = `${parentValue}, ${childValue}`;1273 if (parentConfig === childConfig) {1274 // When both components read using the same config, the two values1275 // must be consistent.1276 if (parentValue !== childValue) {1277 result = 'Oops, tearing!';1278 }1279 }1280 useEffect(() => {1281 Scheduler.unstable_yieldValue('Commit: ' + result);1282 }, [result]);1283 return result;1284 }1285 const root = ReactNoop.createRoot();1286 await act(async () => {1287 root.render(<App parentConfig={configA} childConfig={configB} />);1288 });1289 expect(Scheduler).toHaveYielded(['Parent: 1', 'Child: 2', 'Commit: 1, 2']);1290 await act(async () => {1291 // Switch the parent and the child to read using the same config1292 root.render(<App parentConfig={configB} childConfig={configB} />);1293 // Start rendering the parent, but yield before rendering the child1294 expect(Scheduler).toFlushAndYieldThrough(['Parent: 2']);1295 // Mutate the config. This is at lower priority so that 1) to make sure1296 // it doesn't happen to get batched with the in-progress render, and 2)1297 // so it doesn't interrupt the in-progress render.1298 Scheduler.unstable_runWithPriority(1299 Scheduler.unstable_IdlePriority,1300 () => {1301 source.valueB = '3';1302 },1303 );1304 });1305 expect(Scheduler).toHaveYielded([1306 // The partial render completes1307 'Child: 2',1308 'Commit: 2, 2',1309 // Then we start rendering the low priority mutation1310 'Parent: 3',1311 // Eventually the child corrects itself, because of the check that1312 // occurs when re-subscribing.1313 'Child: 3',1314 'Commit: 3, 3',1315 ]);1316 });1317 // @gate experimental1318 it('should not tear with newly mounted component when updates were scheduled at a lower priority', async () => {1319 const source = createSource('one');1320 const mutableSource = createMutableSource(source);1321 let committedA = null;1322 let committedB = null;1323 const onRender = () => {1324 if (committedB !== null) {1325 expect(committedA).toBe(committedB);1326 }1327 };1328 function ComponentA() {1329 const snapshot = useMutableSource(1330 mutableSource,1331 defaultGetSnapshot,1332 defaultSubscribe,1333 );1334 Scheduler.unstable_yieldValue(`a:${snapshot}`);1335 React.useEffect(() => {1336 committedA = snapshot;1337 }, [snapshot]);1338 return <div>{`a:${snapshot}`}</div>;1339 }1340 function ComponentB() {1341 const snapshot = useMutableSource(1342 mutableSource,1343 defaultGetSnapshot,1344 defaultSubscribe,1345 );1346 Scheduler.unstable_yieldValue(`b:${snapshot}`);1347 React.useEffect(() => {1348 committedB = snapshot;1349 }, [snapshot]);1350 return <div>{`b:${snapshot}`}</div>;1351 }1352 // Mount ComponentA with data version 11353 act(() => {1354 ReactNoop.render(1355 <React.Profiler id="root" onRender={onRender}>...

Full Screen

Full Screen

useMutableSourceHydration-test.js

Source:useMutableSourceHydration-test.js Github

copy

Full Screen

...113 },114 };115 }116 function Component({getSnapshot, label, mutableSource, subscribe}) {117 const snapshot = useMutableSource(mutableSource, getSnapshot, subscribe);118 Scheduler.unstable_yieldValue(`${label}:${snapshot}`);119 return <div>{`${label}:${snapshot}`}</div>;120 }121 // @gate enableUseMutableSource122 it('should render and hydrate', () => {123 const source = createSource('one');124 const mutableSource = createMutableSource(source, param => param.version);125 function TestComponent() {126 return (127 <Component128 label="only"129 getSnapshot={defaultGetSnapshot}130 mutableSource={mutableSource}131 subscribe={defaultSubscribe}...

Full Screen

Full Screen

index.js

Source:index.js Github

copy

Full Screen

...142 }143 return (prevSnapshot = snapshot);144 };145 }, []);146 const snapshot = useMutableSource(147 proxy[MUTABLE_SOURCE],148 getSnapshot,149 subscribe150 );151 const proxyCache = useMemo(() => new WeakMap(), []); // per-hook proxyCache152 return createDeepProxy(snapshot, affected, proxyCache);153};...

Full Screen

Full Screen

demo27.js

Source:demo27.js Github

copy

Full Screen

...32 // 1、 mutableSource 就是我们刚才创建的33 // 2、 第二个是获取数据的方法,useMutableSource会把ref作为参数传入getSnapshot34 // 3、 第三个是订阅事件 useMutableSource会传入一个ref和一个callabck35 // 在组件中每执行一次就会就会把,数据源与获取数据的方式以及新的订阅方法传入36 return React.useMutableSource(mutableSource, getData || getSnapshot, subscribe);37 }38 // 进行数据修改,广播到每个订阅的组件39 const dispatch = (value) => {40 // 修改数据41 ref.current = value;42 // 修改了数据以后,就会执行lisenter方法,然后每个订阅会执行getSnapshot方法43 // 这里的每个listener就是React.useMutableSource时候传入的callback44 ref.listeners.forEach(listener => listener());45 }46 return [47 useStore,48 dispatch,49 ]50}...

Full Screen

Full Screen

Recoil_ReactMode.js

Source:Recoil_ReactMode.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 * @emails oncall+recoil8 * @flow strict-local9 * @format10 */11'use strict';12const React = require('react');13const gkx = require('recoil-shared/util/Recoil_gkx');14export opaque type MutableSource = {};15const createMutableSource: <StoreState, Version>(16 {current: StoreState},17 () => Version,18) => MutableSource =19 // flowlint-next-line unclear-type:off20 (React: any).createMutableSource ?? (React: any).unstable_createMutableSource;21const useMutableSource: <StoreState, T>(22 MutableSource,23 () => T,24 (StoreState, () => void) => () => void,25) => T =26 // flowlint-next-line unclear-type:off27 (React: any).useMutableSource ?? (React: any).unstable_useMutableSource;28// https://github.com/reactwg/react-18/discussions/8629const useSyncExternalStore: <T>(30 subscribe: (() => void) => () => void,31 getSnapshot: () => T,32 getServerSnapshot?: () => T,33) => T =34 // flowlint-next-line unclear-type:off35 (React: any).useSyncExternalStore ??36 // flowlint-next-line unclear-type:off37 (React: any).unstable_useSyncExternalStore;38type ReactMode =39 | 'TRANSITION_SUPPORT'40 | 'SYNC_EXTERNAL_STORE'41 | 'MUTABLE_SOURCE'42 | 'LEGACY';43/**44 * mode: The React API and approach to use for syncing state with React45 * early: Re-renders from Recoil updates occur:46 * 1) earlier47 * 2) in sync with React updates in the same batch48 * 3) before transaction observers instead of after.49 * concurrent: Is the current mode compatible with Concurrent Mode and useTransition()50 */51function reactMode(): {mode: ReactMode, early: boolean, concurrent: boolean} {52 // NOTE: This mode is currently broken with some Suspense cases53 // see Recoil_selector-test.js54 if (gkx('recoil_transition_support')) {55 return {mode: 'TRANSITION_SUPPORT', early: true, concurrent: true};56 }57 if (gkx('recoil_sync_external_store') && useSyncExternalStore != null) {58 return {mode: 'SYNC_EXTERNAL_STORE', early: true, concurrent: false};59 }60 if (61 gkx('recoil_mutable_source') &&62 useMutableSource != null &&63 typeof window !== 'undefined' &&64 !window.$disableRecoilValueMutableSource_TEMP_HACK_DO_NOT_USE65 ) {66 return gkx('recoil_suppress_rerender_in_callback')67 ? {mode: 'MUTABLE_SOURCE', early: true, concurrent: true}68 : {mode: 'MUTABLE_SOURCE', early: false, concurrent: false};69 }70 return gkx('recoil_suppress_rerender_in_callback')71 ? {mode: 'LEGACY', early: true, concurrent: false}72 : {mode: 'LEGACY', early: false, concurrent: false};73}74// TODO Need to figure out if there is a standard/open-source equivalent to see if hot module replacement is happening:75function isFastRefreshEnabled(): boolean {76 // @fb-only: const {isAcceptingUpdate} = require('__debug');77 // @fb-only: return typeof isAcceptingUpdate === 'function' && isAcceptingUpdate();78 return false; // @oss-only79}80module.exports = {81 createMutableSource,82 useMutableSource,83 useSyncExternalStore,84 reactMode,85 isFastRefreshEnabled,...

Full Screen

Full Screen

Recoil_mutableSource.js

Source:Recoil_mutableSource.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 * @emails oncall+recoil8 * @flow strict9 * @format10 */11'use strict';12const React = require('react');13// FIXME T271055928259966014const useMutableSource: Function = // flowlint-line unclear-type:off15 (React: any).useMutableSource ?? (React: any).unstable_useMutableSource; // flowlint-line unclear-type:off16function mutableSourceExists(): boolean {17 return (18 useMutableSource &&19 !(20 typeof window !== 'undefined' &&21 window.$disableRecoilValueMutableSource_TEMP_HACK_DO_NOT_USE22 )23 );24}25module.exports = {26 mutableSourceExists,27 useMutableSource,...

Full Screen

Full Screen

useMutableSource.js

Source:useMutableSource.js Github

copy

Full Screen

1/*2export {3 unstable_createMutableSource as createMutableSource,4 unstable_useMutableSource as useMutableSource,5} from 'react'6*/7// emulation with use-subscription8import { useMemo } from "react";9import { useSubscription } from "use-subscription";10const TARGET = Symbol();11export const createMutableSource = (target, _getVersion) => ({12 [TARGET]: target,13});14export const useMutableSource = (source, getSnapshot, subscribe) => {15 const subscription = useMemo(16 () => ({17 getCurrentValue: () => getSnapshot(source[TARGET]),18 subscribe: (callback) => subscribe(source[TARGET], callback),19 }),20 [source, getSnapshot, subscribe]21 );22 return useSubscription(subscription);...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const { useMutableSource } = require('playwright/lib/server/supplements/recorder/recorderSupplement');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 const source = await page._delegate;8 const { recorderSupplement } = await useMutableSource(source);9 await recorderSupplement.start();10 await recorderSupplement.stop();11 await browser.close();12})();13{14 {

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const source = await page._delegate.useMutableSource();7 console.log(source);8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('playwright');2const source = {3 getSnapshot: () => {4 return { value: 1 };5 },6 subscribe: (callback) => {7 const id = setInterval(() => {8 callback();9 }, 1000);10 return () => clearInterval(id);11 },12};13const mutableSource = useMutableSource(source, () => 1);14const { useSource } = require('playwright');15const playwrightSource = useSource(() => {16 return {17 getSnapshot: () => {18 return { value: 1 };19 },20 subscribe: (callback) => {21 const id = setInterval(() => {22 callback();23 }, 1000);24 return () => clearInterval(id);25 },26 };27});28const { useSource } = require('playwright');29const playwrightSource = useSource(() => {30 return {31 getSnapshot: () => {32 return { value: 1 };33 },34 subscribe: (callback) => {35 const id = setInterval(() => {36 callback();37 }, 1000);38 return () => clearInterval(id);39 },40 };41});42const playwrightSource = useSource(() => {43 return {44 getSnapshot: () => {45 return { value: 1 };46 },47 subscribe: (callback) => {48 const id = setInterval(() => {49 callback();50 }, 1000);51 return () => clearInterval(id);52 },53 };54});55const { useSource } = require('playwright');56const playwrightSource = useSource(() => {57 return {58 getSnapshot: () => {59 return { value: 1 };60 },61 subscribe: (callback) => {62 const id = setInterval(() => {63 callback();64 }, 1000);65 return () => clearInterval(id);66 },67 };68});69const { useSource } = require('playwright');70const playwrightSource = useSource(() => {71 return {72 getSnapshot: () => {73 return { value: 1 };74 },75 subscribe: (callback) => {76 const id = setInterval(() => {77 callback();78 }, 1000);79 return () => clearInterval(id);80 },81 };82});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('@playwright/test/lib/mutableSource');2const { test } = useMutableSource('test');3const { useTestState } = require('@playwright/test/lib/testState');4const testInfo = useTestState();5const { useWorker } = require('@playwright/test/lib/worker');6const workerInfo = useWorker();7const { useFixture } = require('@playwright/test/lib/fixture');8const { test } = useFixture('test');9const { useTestResult } = require('@playwright/test/lib/testResult');10const testResult = useTestResult();11const { useProject } = require('@playwright/test/lib/project');12const projectInfo = useProject();13const { useBrowser } = require('@playwright/test/lib/browser');14const browser = useBrowser();15const { usePage } = require('@playwright/test/lib/page');16const page = usePage();17const { useBrowserContext } = require('@playwright/test/lib/browserContext');18const context = useBrowserContext();19const { useVideo } = require('@playwright/test/lib/video');20const video = useVideo();21const { useArtifacts } = require('@playwright/test/lib/artifacts');22const artifacts = useArtifacts();23const { useTrace } = require('@playwright/test/lib/trace');24const trace = useTrace();25const { useSnapshot } = require('@playwright/test/lib/snapshot');26const snapshot = useSnapshot();27const { useOutput } = require('@playwright/test/lib/output');28const output = useOutput();

Full Screen

Using AI Code Generation

copy

Full Screen

1const {useMutableSource} = require('playwright');2const {createMutableSource} = require('playwright/lib/server/mutableSource');3const {createServer} = require('http');4const {createReadStream} = require('fs');5const {join} = require('path');6const {promisify} = require('util');7const finalhandler = require('finalhandler');8const serveStatic = require('serve-static');9const serve = serveStatic(join(__dirname, 'public'));10const server = createServer((req, res) => {11 const done = finalhandler(req, res);12 serve(req, res, done);13});14const port = 8080;15server.listen(port, () => console.log(`Listening on ${port}`));16const mutableSource = createMutableSource();17const {subscribe, update} = mutableSource;18const readFile = promisify(createReadStream);19const readFileAndSend = async (path) => {20 const stream = readFile(path);21 for await (const chunk of stream) {22 await update(chunk);23 }24};25readFileAndSend(join(__dirname, 'public', 'file.txt'));26const source = useMutableSource(mutableSource, (chunk) => {27 console.log(chunk.toString());28});29const {test} = require('@playwright/test');30test('test', async ({page}) => {31 const element = await page.$('div');32 const text = await element.textContent();33 expect(text).toBe('Hello World!');34});35All contributions are welcome. Please see the [Playwright contributing guide](

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');2const source = useMutableSource();3const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');4const source = useMutableSource();5const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');6const playwright = getPlaywright();7const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');8const source = useMutableSource();9const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');10const playwright = getPlaywright();11const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');12const source = useMutableSource();13const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');14const playwright = getPlaywright();15const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');16const source = useMutableSource();17const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');18const playwright = getPlaywright();19const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');20const source = useMutableSource();21const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');22const playwright = getPlaywright();23const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');24const source = useMutableSource();25const { getPlaywright } = require('playwright-core/lib/server/supplements/mutableSource');26const playwright = getPlaywright();27const { useMutableSource } = require('playwright-core/lib/server/supplements/mutableSource');28const source = useMutableSource();29const { getPlaywright } =

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('playwright');2(async () => {3 const source = await useMutableSource();4 console.log(source);5})();6{ browserName: 'chromium',7 platformName: 'linux' }

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('@playwright/test');2const { test, expect } = useTestModule();3test('useMutableSource', async ({ page }) => {4 const { source, getSnapshot } = useMutableSource();5 expect(await getSnapshot(page)).toContain('Playwright');6});7const { useTestModule } = require('@playwright/test');8module.exports = {9 use: {10 },11};12module.exports.useTestModule = () => {13 const source = new Map();14 const getSnapshot = (page) => page.textContent('text=Playwright');15 return {16 };17};

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('@playwright/test');2const { source } = require('./source');3const mySource = useMutableSource(source, () => {4 return source.value;5});6const { createSource } = require('@playwright/test');7const source = createSource({8});9module.exports = {10};11const { createSource, updateSource } = require('@playwright/test');12const source = createSource({13});14updateSource(source, {15});16const { createSource, updateSource } = require('@playwright/test');17const source = createSource({18});19updateSource(source, {20});21const { createSource, updateSource } = require('@playwright/test');22const source = createSource({23});24updateSource(source, {25});26const { createSource, updateSource } = require('@playwright/test');27const source = createSource({28});29updateSource(source, {30});31const { createSource, updateSource } = require('@playwright/test');32const source = createSource({33});34updateSource(source, {35});36const { createSource, updateSource } = require('@playwright/test');37const source = createSource({

Full Screen

Using AI Code Generation

copy

Full Screen

1const { useMutableSource } = require('@playwright/test');2const { test, expect } = useMutableSource('playwright');3test('test useMutableSource', async ({ page }) => {4 const title = await page.title();5 expect(title).toBe('Playwright');6});

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal 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