How to use merged method in mountebank

Best JavaScript code snippet using mountebank

flamegraph_unittest.ts

Source:flamegraph_unittest.ts Github

copy

Full Screen

1// Copyright (C) 2019 The Android Open Source Project2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14import {mergeCallsites} from './flamegraph_util';15import {CallsiteInfo} from './state';16test('zeroCallsitesMerged', () => {17 const callsites: CallsiteInfo[] = [18 {19 id: 1,20 parentId: -1,21 name: 'A',22 depth: 0,23 totalSize: 10,24 selfSize: 0,25 mapping: 'x',26 merged: false27 },28 {29 id: 2,30 parentId: -1,31 name: 'B',32 depth: 0,33 totalSize: 8,34 selfSize: 0,35 mapping: 'x',36 merged: false37 },38 {39 id: 3,40 parentId: 1,41 name: 'A3',42 depth: 1,43 totalSize: 4,44 selfSize: 0,45 mapping: 'x',46 merged: false47 },48 {49 id: 4,50 parentId: 2,51 name: 'B4',52 depth: 1,53 totalSize: 4,54 selfSize: 0,55 mapping: 'x',56 merged: false57 },58 ];59 const mergedCallsites = mergeCallsites(callsites, 5);60 // Small callsites are not next ot each other, nothing should be changed.61 expect(mergedCallsites).toEqual(callsites);62});63test('zeroCallsitesMerged2', () => {64 const callsites: CallsiteInfo[] = [65 {66 id: 1,67 parentId: -1,68 name: 'A',69 depth: 0,70 totalSize: 10,71 selfSize: 0,72 mapping: 'x',73 merged: false74 },75 {76 id: 2,77 parentId: -1,78 name: 'B',79 depth: 0,80 totalSize: 8,81 selfSize: 0,82 mapping: 'x',83 merged: false84 },85 {86 id: 3,87 parentId: 1,88 name: 'A3',89 depth: 1,90 totalSize: 6,91 selfSize: 0,92 mapping: 'x',93 merged: false94 },95 {96 id: 4,97 parentId: 1,98 name: 'A4',99 depth: 1,100 totalSize: 4,101 selfSize: 0,102 mapping: 'x',103 merged: false104 },105 {106 id: 5,107 parentId: 2,108 name: 'B5',109 depth: 1,110 totalSize: 8,111 selfSize: 0,112 mapping: 'x',113 merged: false114 },115 ];116 const mergedCallsites = mergeCallsites(callsites, 5);117 // Small callsites are not next ot each other, nothing should be changed.118 expect(mergedCallsites).toEqual(callsites);119});120test('twoCallsitesMerged', () => {121 const callsites: CallsiteInfo[] = [122 {123 id: 1,124 parentId: -1,125 name: 'A',126 depth: 0,127 totalSize: 10,128 selfSize: 0,129 mapping: 'x',130 merged: false131 },132 {133 id: 2,134 parentId: 1,135 name: 'A2',136 depth: 1,137 totalSize: 5,138 selfSize: 0,139 mapping: 'x',140 merged: false141 },142 {143 id: 3,144 parentId: 1,145 name: 'A3',146 depth: 1,147 totalSize: 5,148 selfSize: 0,149 mapping: 'x',150 merged: false151 },152 ];153 const mergedCallsites = mergeCallsites(callsites, 6);154 expect(mergedCallsites).toEqual([155 {156 id: 1,157 parentId: -1,158 name: 'A',159 depth: 0,160 totalSize: 10,161 selfSize: 0,162 mapping: 'x',163 merged: false164 },165 {166 id: 2,167 parentId: 1,168 name: '[merged]',169 depth: 1,170 totalSize: 10,171 selfSize: 0,172 mapping: 'x',173 merged: true174 },175 ]);176});177test('manyCallsitesMerged', () => {178 const callsites: CallsiteInfo[] = [179 {180 id: 1,181 parentId: -1,182 name: 'A',183 depth: 0,184 totalSize: 10,185 selfSize: 0,186 mapping: 'x',187 merged: false188 },189 {190 id: 2,191 parentId: 1,192 name: 'A2',193 depth: 1,194 totalSize: 5,195 selfSize: 0,196 mapping: 'x',197 merged: false198 },199 {200 id: 3,201 parentId: 1,202 name: 'A3',203 depth: 1,204 totalSize: 3,205 selfSize: 0,206 mapping: 'x',207 merged: false208 },209 {210 id: 4,211 parentId: 1,212 name: 'A4',213 depth: 1,214 totalSize: 1,215 selfSize: 0,216 mapping: 'x',217 merged: false218 },219 {220 id: 5,221 parentId: 1,222 name: 'A5',223 depth: 1,224 totalSize: 1,225 selfSize: 0,226 mapping: 'x',227 merged: false228 },229 {230 id: 6,231 parentId: 3,232 name: 'A36',233 depth: 2,234 totalSize: 1,235 selfSize: 0,236 mapping: 'x',237 merged: false238 },239 {240 id: 7,241 parentId: 4,242 name: 'A47',243 depth: 2,244 totalSize: 1,245 selfSize: 0,246 mapping: 'x',247 merged: false248 },249 {250 id: 8,251 parentId: 5,252 name: 'A58',253 depth: 2,254 totalSize: 1,255 selfSize: 0,256 mapping: 'x',257 merged: false258 },259 ];260 const expectedMergedCallsites: CallsiteInfo[] = [261 {262 id: 1,263 parentId: -1,264 name: 'A',265 depth: 0,266 totalSize: 10,267 selfSize: 0,268 mapping: 'x',269 merged: false270 },271 {272 id: 2,273 parentId: 1,274 name: 'A2',275 depth: 1,276 totalSize: 5,277 selfSize: 0,278 mapping: 'x',279 merged: false280 },281 {282 id: 3,283 parentId: 1,284 name: '[merged]',285 depth: 1,286 totalSize: 5,287 selfSize: 0,288 mapping: 'x',289 merged: true290 },291 {292 id: 6,293 parentId: 3,294 name: '[merged]',295 depth: 2,296 totalSize: 3,297 selfSize: 0,298 mapping: 'x',299 merged: true300 },301 ];302 const mergedCallsites = mergeCallsites(callsites, 4);303 // In this case, callsites A3, A4 and A5 should be merged since they are304 // smaller then 4 and are on same depth with same parent. Callsites A36, A47305 // and A58 should also be merged since their parents are merged.306 expect(mergedCallsites).toEqual(expectedMergedCallsites);307});308test('manyCallsitesMergedWithoutChildren', () => {309 const callsites: CallsiteInfo[] = [310 {311 id: 1,312 parentId: -1,313 name: 'A',314 depth: 0,315 totalSize: 5,316 selfSize: 0,317 mapping: 'x',318 merged: false319 },320 {321 id: 2,322 parentId: -1,323 name: 'B',324 depth: 0,325 totalSize: 5,326 selfSize: 0,327 mapping: 'x',328 merged: false329 },330 {331 id: 3,332 parentId: 1,333 name: 'A3',334 depth: 1,335 totalSize: 3,336 selfSize: 0,337 mapping: 'x',338 merged: false339 },340 {341 id: 4,342 parentId: 1,343 name: 'A4',344 depth: 1,345 totalSize: 1,346 selfSize: 0,347 mapping: 'x',348 merged: false349 },350 {351 id: 5,352 parentId: 1,353 name: 'A5',354 depth: 1,355 totalSize: 1,356 selfSize: 0,357 mapping: 'x',358 merged: false359 },360 {361 id: 6,362 parentId: 2,363 name: 'B6',364 depth: 1,365 totalSize: 5,366 selfSize: 0,367 mapping: 'x',368 merged: false369 },370 {371 id: 7,372 parentId: 4,373 name: 'A47',374 depth: 2,375 totalSize: 1,376 selfSize: 0,377 mapping: 'x',378 merged: false379 },380 {381 id: 8,382 parentId: 6,383 name: 'B68',384 depth: 2,385 totalSize: 1,386 selfSize: 0,387 mapping: 'x',388 merged: false389 },390 ];391 const expectedMergedCallsites: CallsiteInfo[] = [392 {393 id: 1,394 parentId: -1,395 name: 'A',396 depth: 0,397 totalSize: 5,398 selfSize: 0,399 mapping: 'x',400 merged: false401 },402 {403 id: 2,404 parentId: -1,405 name: 'B',406 depth: 0,407 totalSize: 5,408 selfSize: 0,409 mapping: 'x',410 merged: false411 },412 {413 id: 3,414 parentId: 1,415 name: '[merged]',416 depth: 1,417 totalSize: 5,418 selfSize: 0,419 mapping: 'x',420 merged: true421 },422 {423 id: 6,424 parentId: 2,425 name: 'B6',426 depth: 1,427 totalSize: 5,428 selfSize: 0,429 mapping: 'x',430 merged: false431 },432 {433 id: 7,434 parentId: 3,435 name: 'A47',436 depth: 2,437 totalSize: 1,438 selfSize: 0,439 mapping: 'x',440 merged: false441 },442 {443 id: 8,444 parentId: 6,445 name: 'B68',446 depth: 2,447 totalSize: 1,448 selfSize: 0,449 mapping: 'x',450 merged: false451 },452 ];453 const mergedCallsites = mergeCallsites(callsites, 4);454 // In this case, callsites A3, A4 and A5 should be merged since they are455 // smaller then 4 and are on same depth with same parent. Callsite A47456 // should not be merged with B68 althought they are small because they don't457 // have sam parent. A47 should now have parent A3 because A4 is merged.458 expect(mergedCallsites).toEqual(expectedMergedCallsites);459});460test('smallCallsitesNotNextToEachOtherInArray', () => {461 const callsites: CallsiteInfo[] = [462 {463 id: 1,464 parentId: -1,465 name: 'A',466 depth: 0,467 totalSize: 20,468 selfSize: 0,469 mapping: 'x',470 merged: false471 },472 {473 id: 2,474 parentId: 1,475 name: 'A2',476 depth: 1,477 totalSize: 8,478 selfSize: 0,479 mapping: 'x',480 merged: false481 },482 {483 id: 3,484 parentId: 1,485 name: 'A3',486 depth: 1,487 totalSize: 1,488 selfSize: 0,489 mapping: 'x',490 merged: false491 },492 {493 id: 4,494 parentId: 1,495 name: 'A4',496 depth: 1,497 totalSize: 8,498 selfSize: 0,499 mapping: 'x',500 merged: false501 },502 {503 id: 5,504 parentId: 1,505 name: 'A5',506 depth: 1,507 totalSize: 3,508 selfSize: 0,509 mapping: 'x',510 merged: false511 },512 ];513 const expectedMergedCallsites: CallsiteInfo[] = [514 {515 id: 1,516 parentId: -1,517 name: 'A',518 depth: 0,519 totalSize: 20,520 selfSize: 0,521 mapping: 'x',522 merged: false523 },524 {525 id: 2,526 parentId: 1,527 name: 'A2',528 depth: 1,529 totalSize: 8,530 selfSize: 0,531 mapping: 'x',532 merged: false533 },534 {535 id: 3,536 parentId: 1,537 name: '[merged]',538 depth: 1,539 totalSize: 4,540 selfSize: 0,541 mapping: 'x',542 merged: true543 },544 {545 id: 4,546 parentId: 1,547 name: 'A4',548 depth: 1,549 totalSize: 8,550 selfSize: 0,551 mapping: 'x',552 merged: false553 },554 ];555 const mergedCallsites = mergeCallsites(callsites, 4);556 // In this case, callsites A3, A4 and A5 should be merged since they are557 // smaller then 4 and are on same depth with same parent. Callsite A47558 // should not be merged with B68 althought they are small because they don't559 // have sam parent. A47 should now have parent A3 because A4 is merged.560 expect(mergedCallsites).toEqual(expectedMergedCallsites);561});562test('smallCallsitesNotMerged', () => {563 const callsites: CallsiteInfo[] = [564 {565 id: 1,566 parentId: -1,567 name: 'A',568 depth: 0,569 totalSize: 10,570 selfSize: 0,571 mapping: 'x',572 merged: false573 },574 {575 id: 2,576 parentId: 1,577 name: 'A2',578 depth: 1,579 totalSize: 2,580 selfSize: 0,581 mapping: 'x',582 merged: false583 },584 {585 id: 3,586 parentId: 1,587 name: 'A3',588 depth: 1,589 totalSize: 2,590 selfSize: 0,591 mapping: 'x',592 merged: false593 },594 ];595 const mergedCallsites = mergeCallsites(callsites, 1);596 expect(mergedCallsites).toEqual(callsites);597});598test('mergingRootCallsites', () => {599 const callsites: CallsiteInfo[] = [600 {601 id: 1,602 parentId: -1,603 name: 'A',604 depth: 0,605 totalSize: 10,606 selfSize: 0,607 mapping: 'x',608 merged: false609 },610 {611 id: 2,612 parentId: -1,613 name: 'B',614 depth: 0,615 totalSize: 2,616 selfSize: 0,617 mapping: 'x',618 merged: false619 },620 ];621 const mergedCallsites = mergeCallsites(callsites, 20);622 expect(mergedCallsites).toEqual([623 {624 id: 1,625 parentId: -1,626 name: '[merged]',627 depth: 0,628 totalSize: 12,629 selfSize: 0,630 mapping: 'x',631 merged: true632 },633 ]);634});635test('largerFlamegraph', () => {636 const data: CallsiteInfo[] = [637 {638 id: 1,639 parentId: -1,640 name: 'A',641 depth: 0,642 totalSize: 60,643 selfSize: 0,644 mapping: 'x',645 merged: false646 },647 {648 id: 2,649 parentId: -1,650 name: 'B',651 depth: 0,652 totalSize: 40,653 selfSize: 0,654 mapping: 'x',655 merged: false656 },657 {658 id: 3,659 parentId: 1,660 name: 'A3',661 depth: 1,662 totalSize: 25,663 selfSize: 0,664 mapping: 'x',665 merged: false666 },667 {668 id: 4,669 parentId: 1,670 name: 'A4',671 depth: 1,672 totalSize: 15,673 selfSize: 0,674 mapping: 'x',675 merged: false676 },677 {678 id: 5,679 parentId: 1,680 name: 'A5',681 depth: 1,682 totalSize: 10,683 selfSize: 0,684 mapping: 'x',685 merged: false686 },687 {688 id: 6,689 parentId: 1,690 name: 'A6',691 depth: 1,692 totalSize: 10,693 selfSize: 0,694 mapping: 'x',695 merged: false696 },697 {698 id: 7,699 parentId: 2,700 name: 'B7',701 depth: 1,702 totalSize: 30,703 selfSize: 0,704 mapping: 'x',705 merged: false706 },707 {708 id: 8,709 parentId: 2,710 name: 'B8',711 depth: 1,712 totalSize: 10,713 selfSize: 0,714 mapping: 'x',715 merged: false716 },717 {718 id: 9,719 parentId: 3,720 name: 'A39',721 depth: 2,722 totalSize: 20,723 selfSize: 0,724 mapping: 'x',725 merged: false726 },727 {728 id: 10,729 parentId: 4,730 name: 'A410',731 depth: 2,732 totalSize: 10,733 selfSize: 0,734 mapping: 'x',735 merged: false736 },737 {738 id: 11,739 parentId: 4,740 name: 'A411',741 depth: 2,742 totalSize: 3,743 selfSize: 0,744 mapping: 'x',745 merged: false746 },747 {748 id: 12,749 parentId: 4,750 name: 'A412',751 depth: 2,752 totalSize: 2,753 selfSize: 0,754 mapping: 'x',755 merged: false756 },757 {758 id: 13,759 parentId: 5,760 name: 'A513',761 depth: 2,762 totalSize: 5,763 selfSize: 0,764 mapping: 'x',765 merged: false766 },767 {768 id: 14,769 parentId: 5,770 name: 'A514',771 depth: 2,772 totalSize: 5,773 selfSize: 0,774 mapping: 'x',775 merged: false776 },777 {778 id: 15,779 parentId: 7,780 name: 'A715',781 depth: 2,782 totalSize: 10,783 selfSize: 0,784 mapping: 'x',785 merged: false786 },787 {788 id: 16,789 parentId: 7,790 name: 'A716',791 depth: 2,792 totalSize: 5,793 selfSize: 0,794 mapping: 'x',795 merged: false796 },797 {798 id: 17,799 parentId: 7,800 name: 'A717',801 depth: 2,802 totalSize: 5,803 selfSize: 0,804 mapping: 'x',805 merged: false806 },807 {808 id: 18,809 parentId: 7,810 name: 'A718',811 depth: 2,812 totalSize: 5,813 selfSize: 0,814 mapping: 'x',815 merged: false816 },817 {818 id: 19,819 parentId: 9,820 name: 'A919',821 depth: 3,822 totalSize: 10,823 selfSize: 0,824 mapping: 'x',825 merged: false826 },827 {828 id: 20,829 parentId: 17,830 name: 'A1720',831 depth: 3,832 totalSize: 2,833 selfSize: 0,834 mapping: 'x',835 merged: false836 },837 ];838 const expectedData: CallsiteInfo[] = [839 {840 id: 1,841 parentId: -1,842 name: 'A',843 depth: 0,844 totalSize: 60,845 selfSize: 0,846 mapping: 'x',847 merged: false848 },849 {850 id: 2,851 parentId: -1,852 name: 'B',853 depth: 0,854 totalSize: 40,855 selfSize: 0,856 mapping: 'x',857 merged: false858 },859 {860 id: 3,861 parentId: 1,862 name: 'A3',863 depth: 1,864 totalSize: 25,865 selfSize: 0,866 mapping: 'x',867 merged: false868 },869 {870 id: 4,871 parentId: 1,872 name: '[merged]',873 depth: 1,874 totalSize: 35,875 selfSize: 0,876 mapping: 'x',877 merged: true878 },879 {880 id: 7,881 parentId: 2,882 name: 'B7',883 depth: 1,884 totalSize: 30,885 selfSize: 0,886 mapping: 'x',887 merged: false888 },889 {890 id: 8,891 parentId: 2,892 name: 'B8',893 depth: 1,894 totalSize: 10,895 selfSize: 0,896 mapping: 'x',897 merged: false898 },899 {900 id: 9,901 parentId: 3,902 name: 'A39',903 depth: 2,904 totalSize: 20,905 selfSize: 0,906 mapping: 'x',907 merged: false908 },909 {910 id: 10,911 parentId: 4,912 name: '[merged]',913 depth: 2,914 totalSize: 25,915 selfSize: 0,916 mapping: 'x',917 merged: true918 },919 {920 id: 15,921 parentId: 7,922 name: '[merged]',923 depth: 2,924 totalSize: 25,925 selfSize: 0,926 mapping: 'x',927 merged: true928 },929 {930 id: 19,931 parentId: 9,932 name: 'A919',933 depth: 3,934 totalSize: 10,935 selfSize: 0,936 mapping: 'x',937 merged: false938 },939 {940 id: 20,941 parentId: 15,942 name: 'A1720',943 depth: 3,944 totalSize: 2,945 selfSize: 0,946 mapping: 'x',947 merged: false948 },949 ];950 // In this case, on depth 1, callsites A4, A5 and A6 should be merged and951 // initiate merging of their children A410, A411, A412, A513, A514. On depth2,952 // callsites A715, A716, A717 and A718 should be merged.953 const actualData = mergeCallsites(data, 16);954 expect(actualData).toEqual(expectedData);...

Full Screen

Full Screen

cellsCollection.unit.js

Source:cellsCollection.unit.js Github

copy

Full Screen

1import MergedCellsCollection from '../cellsCollection';2describe('MergeCells', () => {3 describe('MergedCellsCollection', () => {4 const hotMock = {5 render: () => {6 },7 countCols: () => 100,8 countRows: () => 100,9 };10 describe('`add` method', () => {11 it('should add a merged cell object to the array of merged cells', () => {12 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });13 mergedCellsCollection.add({14 row: 0,15 col: 1,16 rowspan: 3,17 colspan: 418 });19 mergedCellsCollection.add({20 row: 10,21 col: 11,22 rowspan: 3,23 colspan: 424 });25 mergedCellsCollection.add({26 row: 20,27 col: 21,28 rowspan: 3,29 colspan: 430 });31 expect(mergedCellsCollection.mergedCells.length).toEqual(3);32 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);33 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);34 expect(mergedCellsCollection.mergedCells[0].rowspan).toEqual(3);35 expect(mergedCellsCollection.mergedCells[0].colspan).toEqual(4);36 expect(mergedCellsCollection.mergedCells[1].row).toEqual(10);37 expect(mergedCellsCollection.mergedCells[1].col).toEqual(11);38 expect(mergedCellsCollection.mergedCells[1].rowspan).toEqual(3);39 expect(mergedCellsCollection.mergedCells[1].colspan).toEqual(4);40 expect(mergedCellsCollection.mergedCells[2].row).toEqual(20);41 expect(mergedCellsCollection.mergedCells[2].col).toEqual(21);42 expect(mergedCellsCollection.mergedCells[2].rowspan).toEqual(3);43 expect(mergedCellsCollection.mergedCells[2].colspan).toEqual(4);44 });45 it('should not add new merged cells and throw an appropriate warning, if the merged cell is overlapping any other ' +46 'previously declared merged cell', () => {47 const warnSpy = spyOn(console, 'warn');48 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });49 const newMergedCells = [50 {51 row: 0,52 col: 1,53 rowspan: 3,54 colspan: 455 },56 {57 row: 1,58 col: 2,59 rowspan: 3,60 colspan: 461 },62 {63 row: 20,64 col: 21,65 rowspan: 3,66 colspan: 467 }];68 mergedCellsCollection.add(newMergedCells[0]);69 mergedCellsCollection.add(newMergedCells[1]);70 mergedCellsCollection.add(newMergedCells[2]);71 expect(warnSpy).toHaveBeenCalledWith(MergedCellsCollection.IS_OVERLAPPING_WARNING(newMergedCells[1]));72 expect(mergedCellsCollection.mergedCells.length).toEqual(2);73 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);74 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);75 expect(mergedCellsCollection.mergedCells[1].row).toEqual(20);76 expect(mergedCellsCollection.mergedCells[1].col).toEqual(21);77 });78 });79 describe('`remove` method', () => {80 it('should remove a merged cell object from the array of merged cells by passing the starting coordinates', () => {81 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });82 mergedCellsCollection.add({83 row: 0,84 col: 1,85 rowspan: 3,86 colspan: 487 });88 mergedCellsCollection.add({89 row: 10,90 col: 11,91 rowspan: 3,92 colspan: 493 });94 mergedCellsCollection.add({95 row: 20,96 col: 21,97 rowspan: 3,98 colspan: 499 });100 mergedCellsCollection.remove(10, 11);101 expect(mergedCellsCollection.mergedCells.length).toEqual(2);102 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);103 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);104 expect(mergedCellsCollection.mergedCells[0].rowspan).toEqual(3);105 expect(mergedCellsCollection.mergedCells[0].colspan).toEqual(4);106 expect(mergedCellsCollection.mergedCells[1].row).toEqual(20);107 expect(mergedCellsCollection.mergedCells[1].col).toEqual(21);108 expect(mergedCellsCollection.mergedCells[1].rowspan).toEqual(3);109 expect(mergedCellsCollection.mergedCells[1].colspan).toEqual(4);110 });111 it('should remove a merged cell object from the array of merged cells by passing the coordinates from the middle of the merged cell', () => {112 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });113 mergedCellsCollection.add({114 row: 0,115 col: 1,116 rowspan: 3,117 colspan: 4118 });119 mergedCellsCollection.add({120 row: 10,121 col: 11,122 rowspan: 3,123 colspan: 4124 });125 mergedCellsCollection.add({126 row: 20,127 col: 21,128 rowspan: 3,129 colspan: 4130 });131 mergedCellsCollection.remove(12, 13);132 expect(mergedCellsCollection.mergedCells.length).toEqual(2);133 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);134 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);135 expect(mergedCellsCollection.mergedCells[0].rowspan).toEqual(3);136 expect(mergedCellsCollection.mergedCells[0].colspan).toEqual(4);137 expect(mergedCellsCollection.mergedCells[1].row).toEqual(20);138 expect(mergedCellsCollection.mergedCells[1].col).toEqual(21);139 expect(mergedCellsCollection.mergedCells[1].rowspan).toEqual(3);140 expect(mergedCellsCollection.mergedCells[1].colspan).toEqual(4);141 });142 });143 describe('`get` method', () => {144 it('should get a merged cell object from the array of merged cells by passing the starting coordinates', () => {145 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });146 mergedCellsCollection.add({147 row: 0,148 col: 1,149 rowspan: 3,150 colspan: 4151 });152 mergedCellsCollection.add({153 row: 10,154 col: 11,155 rowspan: 3,156 colspan: 4157 });158 mergedCellsCollection.add({159 row: 20,160 col: 21,161 rowspan: 3,162 colspan: 4163 });164 const wantedCollection = mergedCellsCollection.get(10, 11);165 expect(wantedCollection.row).toEqual(10);166 expect(wantedCollection.col).toEqual(11);167 expect(wantedCollection.rowspan).toEqual(3);168 expect(wantedCollection.colspan).toEqual(4);169 });170 it('should get a merged cell object from the array of merged cells by passing coordinates from the middle of the merged cell', () => {171 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });172 mergedCellsCollection.add({173 row: 0,174 col: 1,175 rowspan: 3,176 colspan: 4177 });178 mergedCellsCollection.add({179 row: 10,180 col: 11,181 rowspan: 3,182 colspan: 4183 });184 mergedCellsCollection.add({185 row: 20,186 col: 21,187 rowspan: 3,188 colspan: 4189 });190 const wantedCollection = mergedCellsCollection.get(12, 13);191 expect(wantedCollection.row).toEqual(10);192 expect(wantedCollection.col).toEqual(11);193 expect(wantedCollection.rowspan).toEqual(3);194 expect(wantedCollection.colspan).toEqual(4);195 });196 });197 describe('`getByRange` method', () => {198 it('should get a merged cell object from the array of merged cells by passing coordinates from the middle of the merged cell', () => {199 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });200 mergedCellsCollection.add({201 row: 0,202 col: 1,203 rowspan: 3,204 colspan: 4205 });206 mergedCellsCollection.add({207 row: 10,208 col: 11,209 rowspan: 3,210 colspan: 4211 });212 mergedCellsCollection.add({213 row: 20,214 col: 21,215 rowspan: 3,216 colspan: 4217 });218 const wantedCollection = mergedCellsCollection.getByRange({219 from: {220 row: 12,221 col: 12,222 },223 to: {224 row: 12,225 col: 13226 }227 });228 expect(wantedCollection.row).toEqual(10);229 expect(wantedCollection.col).toEqual(11);230 expect(wantedCollection.rowspan).toEqual(3);231 expect(wantedCollection.colspan).toEqual(4);232 });233 });234 describe('`getWithinRange` method', () => {235 it('should get an array of merged cells within the provided range', () => {236 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });237 mergedCellsCollection.add({238 row: 0,239 col: 1,240 rowspan: 3,241 colspan: 4242 });243 mergedCellsCollection.add({244 row: 10,245 col: 11,246 rowspan: 3,247 colspan: 4248 });249 mergedCellsCollection.add({250 row: 20,251 col: 21,252 rowspan: 3,253 colspan: 4254 });255 const wantedCollections = mergedCellsCollection.getWithinRange({256 from: {257 row: 0,258 col: 0,259 },260 to: {261 row: 19,262 col: 20263 }264 });265 expect(wantedCollections.length).toEqual(2);266 expect(wantedCollections[0].row).toEqual(0);267 expect(wantedCollections[0].col).toEqual(1);268 expect(wantedCollections[0].rowspan).toEqual(3);269 expect(wantedCollections[0].colspan).toEqual(4);270 expect(wantedCollections[1].row).toEqual(10);271 expect(wantedCollections[1].col).toEqual(11);272 expect(wantedCollections[1].rowspan).toEqual(3);273 expect(wantedCollections[1].colspan).toEqual(4);274 });275 });276 describe('`shiftCollections` method', () => {277 it('should shift all the appropriate merged cells in the provided direction', () => {278 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });279 mergedCellsCollection.add({280 row: 0,281 col: 1,282 rowspan: 3,283 colspan: 4284 });285 mergedCellsCollection.add({286 row: 10,287 col: 11,288 rowspan: 3,289 colspan: 4290 });291 mergedCellsCollection.add({292 row: 20,293 col: 21,294 rowspan: 3,295 colspan: 4296 });297 mergedCellsCollection.shiftCollections('down', 0, 5);298 expect(mergedCellsCollection.mergedCells[0].row).toEqual(5);299 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);300 expect(mergedCellsCollection.mergedCells[1].row).toEqual(15);301 expect(mergedCellsCollection.mergedCells[1].col).toEqual(11);302 expect(mergedCellsCollection.mergedCells[2].row).toEqual(25);303 expect(mergedCellsCollection.mergedCells[2].col).toEqual(21);304 mergedCellsCollection.shiftCollections('right', 0, 5);305 expect(mergedCellsCollection.mergedCells[0].row).toEqual(5);306 expect(mergedCellsCollection.mergedCells[0].col).toEqual(6);307 expect(mergedCellsCollection.mergedCells[1].row).toEqual(15);308 expect(mergedCellsCollection.mergedCells[1].col).toEqual(16);309 expect(mergedCellsCollection.mergedCells[2].row).toEqual(25);310 expect(mergedCellsCollection.mergedCells[2].col).toEqual(26);311 mergedCellsCollection.shiftCollections('up', 0, 5);312 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);313 expect(mergedCellsCollection.mergedCells[0].col).toEqual(6);314 expect(mergedCellsCollection.mergedCells[1].row).toEqual(10);315 expect(mergedCellsCollection.mergedCells[1].col).toEqual(16);316 expect(mergedCellsCollection.mergedCells[2].row).toEqual(20);317 expect(mergedCellsCollection.mergedCells[2].col).toEqual(26);318 mergedCellsCollection.shiftCollections('left', 0, 5);319 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);320 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);321 expect(mergedCellsCollection.mergedCells[1].row).toEqual(10);322 expect(mergedCellsCollection.mergedCells[1].col).toEqual(11);323 expect(mergedCellsCollection.mergedCells[2].row).toEqual(20);324 expect(mergedCellsCollection.mergedCells[2].col).toEqual(21);325 });326 it('should resize the merged cell (and shift the merged cells that follow) if the change happened inside a merged cell', () => {327 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });328 mergedCellsCollection.add({329 row: 0,330 col: 1,331 rowspan: 3,332 colspan: 4333 });334 mergedCellsCollection.add({335 row: 10,336 col: 11,337 rowspan: 3,338 colspan: 4339 });340 mergedCellsCollection.add({341 row: 20,342 col: 21,343 rowspan: 3,344 colspan: 4345 });346 mergedCellsCollection.shiftCollections('down', 1, 5);347 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);348 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);349 expect(mergedCellsCollection.mergedCells[0].rowspan).toEqual(8);350 expect(mergedCellsCollection.mergedCells[1].row).toEqual(15);351 expect(mergedCellsCollection.mergedCells[1].col).toEqual(11);352 expect(mergedCellsCollection.mergedCells[1].rowspan).toEqual(3);353 expect(mergedCellsCollection.mergedCells[2].row).toEqual(25);354 expect(mergedCellsCollection.mergedCells[2].col).toEqual(21);355 expect(mergedCellsCollection.mergedCells[2].rowspan).toEqual(3);356 mergedCellsCollection.shiftCollections('right', 2, 5);357 expect(mergedCellsCollection.mergedCells[0].row).toEqual(0);358 expect(mergedCellsCollection.mergedCells[0].col).toEqual(1);359 expect(mergedCellsCollection.mergedCells[0].rowspan).toEqual(8);360 expect(mergedCellsCollection.mergedCells[0].colspan).toEqual(9);361 expect(mergedCellsCollection.mergedCells[1].row).toEqual(15);362 expect(mergedCellsCollection.mergedCells[1].col).toEqual(16);363 expect(mergedCellsCollection.mergedCells[1].rowspan).toEqual(3);364 expect(mergedCellsCollection.mergedCells[2].row).toEqual(25);365 expect(mergedCellsCollection.mergedCells[2].col).toEqual(26);366 expect(mergedCellsCollection.mergedCells[2].rowspan).toEqual(3);367 });368 });369 describe('`isOverlapping` method', () => {370 it('should return whether the provided merged cell overlaps with the others in the merged cell', () => {371 const mergedCellsCollection = new MergedCellsCollection({ hot: hotMock });372 mergedCellsCollection.add({373 row: 0,374 col: 1,375 rowspan: 3,376 colspan: 4377 });378 mergedCellsCollection.add({379 row: 10,380 col: 11,381 rowspan: 3,382 colspan: 4383 });384 mergedCellsCollection.add({385 row: 20,386 col: 21,387 rowspan: 3,388 colspan: 4389 });390 expect(mergedCellsCollection.isOverlapping({ row: 30, col: 30, rowspan: 3, colspan: 3 })).toEqual(false);391 expect(mergedCellsCollection.isOverlapping({ row: 2, col: 2, rowspan: 3, colspan: 3 })).toEqual(true);392 expect(mergedCellsCollection.isOverlapping({ row: 9, col: 9, rowspan: 3, colspan: 3 })).toEqual(true);393 expect(mergedCellsCollection.isOverlapping({ row: 21, col: 19, rowspan: 5, colspan: 5 })).toEqual(true);394 expect(mergedCellsCollection.isOverlapping({ row: 21, col: 22, rowspan: 5, colspan: 5 })).toEqual(true);395 expect(mergedCellsCollection.isOverlapping({ row: 24, col: 25, rowspan: 5, colspan: 5 })).toEqual(false);396 });397 });398 });...

Full Screen

Full Screen

Api.js

Source:Api.js Github

copy

Full Screen

1// a library to wrap and simplify api calls2import apisauce from 'apisauce'3import { merge } from 'ramda'4// import ApiElectron from '../Services/ApiElectron'5// import {getAccessToken} from '../Utils/Utils'6// our "constructor"7const create = (baseURL = 'https://jsonplaceholder.typicode.com/') => {8 // ------9 // STEP 110 // ------11 //12 // Create and configure an apisauce-based api object.13 //14 const API_REMOTE = apisauce.create({15 // base URL is read from the "constructor"16 baseURL,17 // here are some default headers18 headers: {19 // 'Cache-Control': 'no-cache',20 // 'Accept': '*/*',21 'Content-Type': 'application/json',22 // 'Auth': 'Bearer ' + getAccessToken()23 // 'Content-Type': 'application/x-www-form-urlencoded'24 'Access-Control-Allow-Origin': '*'25 // 'tesss': 'ok'26 // 'Access-Control-Request-Method': 'POST'27 // 'Access-Control-Allow-Credentials': 'true',28 // 'content-type': 'application/x-www-form-urlencoded'29 // accept: 'application/vnd.api+json',30 // 'content-type': 'application/vnd.api+json'31 // 'Access-Control-Expose-Headers': 'X-My-Custom-Header, X-Another-Custom-Header'32 },33 xsrfCookieName: 'myCatx',34 // credentials: 'include',35 // 10 second timeout...36 timeout: 1000037 })38 // ------39 // STEP 240 // ------41 //42 // Define some functions that call the api. The goal is to provide43 // a thin wrapper of the api layer providing nicer feeling functions44 // rather than "get", "post" and friends.45 //46 // I generally don't like wrapping the output at this level because47 // sometimes specific actions need to be take on `403` or `401`, etc.48 //49 // Since we can't hide from that, we embrace it by getting out of the50 // way at this level.51 //52 // Define API Constants53 // ------54 // STEP 355 // ------56 //57 // Return back a collection of functions that we would consider our58 // interface. Most of the time it'll be just the list of all the59 // methods in step 2.60 //61 // Notice we're not returning back the `api` created in step 1? That's62 // because it is scoped privately. This is one way to create truly63 // private scoped goodies in JavaScript.64 //65 API_REMOTE.setHeader('channelid', 'WEB')66 let api = API_REMOTE67 // let ipcRenderer = {68 // send: () => {},69 // on: () => {}70 // }71 // let server = ''72 // let neDBDataPath = ''73 // if (window.require) {74 // ipcRenderer = window.require('electron').ipcRenderer75 // server = 'electron'76 // }77 // api = (server === 'electron') ? new ApiElectron(ipcRenderer) : API_REMOTE78 let apiMerged = {}79 // merge api80 // paymentpage81 // apiMerged = merge(apiMerged, require('../Containers/Paymentpage/api').create(api))82 // apiMerged = merge(apiMerged, require('../Containers/Qrcode/api').create(api))83 // begin Ignite-Entity-Login84 // apiMerged = merge(apiMerged, require('../Containers/Login/api').create(api))85 // apiMerged = merge(apiMerged, require('../features/Signup/api').create(api))86 // apiMerged = merge(apiMerged, require('../features/Privilege/api').create(api))87 // apiMerged = merge(apiMerged, require('../Containers/ForgetPassword/api').create(api))88 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/Transaction/api').create(api))89 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/TopupEmoney/api').create(api))90 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/PayBill/api').create(api))91 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/ModalQrMerchant/api').create(api))92 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/Profile/api').create(api))93 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/ModalChangePassword/api').create(api))94 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/Dashboard/api').create(api))95 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/Settlement/api').create(api))96 // apiMerged = merge(apiMerged, require('../Containers/RpMerchant/MerchantRelatedInstitution/api').create(api))97 // apiMerged = merge(apiMerged, require('../features/TablePagination/api').create(api))98 // apiMerged = merge(apiMerged, require('../features/CourseEnrollment/api').create(api))99 // apiMerged = merge(apiMerged, require('../features/ChangePassword/api').create(api))100 apiMerged = merge(apiMerged, {})101 return {102 ...apiMerged103 }104}105// let's return back our create method as the default.106export default {107 create...

Full Screen

Full Screen

mergeEtags.js

Source:mergeEtags.js Github

copy

Full Screen

1/*2 MIT License http://www.opensource.org/licenses/mit-license.php3 Author Tobias Koppers @sokra4*/5"use strict";6/** @typedef {import("../Cache").Etag} Etag */7class MergedEtag {8 /**9 * @param {Etag} a first10 * @param {Etag} b second11 */12 constructor(a, b) {13 this.a = a;14 this.b = b;15 }16 toString() {17 return `${this.a.toString()}|${this.b.toString()}`;18 }19}20const dualObjectMap = new WeakMap();21const objectStringMap = new WeakMap();22/**23 * @param {Etag} a first24 * @param {Etag} b second25 * @returns {Etag} result26 */27const mergeEtags = (a, b) => {28 if (typeof a === "string") {29 if (typeof b === "string") {30 return `${a}|${b}`;31 } else {32 const temp = b;33 b = a;34 a = temp;35 }36 } else {37 if (typeof b !== "string") {38 // both a and b are objects39 let map = dualObjectMap.get(a);40 if (map === undefined) {41 dualObjectMap.set(a, (map = new WeakMap()));42 }43 const mergedEtag = map.get(b);44 if (mergedEtag === undefined) {45 const newMergedEtag = new MergedEtag(a, b);46 map.set(b, newMergedEtag);47 return newMergedEtag;48 } else {49 return mergedEtag;50 }51 }52 }53 // a is object, b is string54 let map = objectStringMap.get(a);55 if (map === undefined) {56 objectStringMap.set(a, (map = new Map()));57 }58 const mergedEtag = map.get(b);59 if (mergedEtag === undefined) {60 const newMergedEtag = new MergedEtag(a, b);61 map.set(b, newMergedEtag);62 return newMergedEtag;63 } else {64 return mergedEtag;65 }66};...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const mb = require('mountebank');2const port = 2525;3 {4 {5 {6 "is": {7 "headers": {8 },9 "body": {10 }11 }12 }13 }14 }15];16mb.start({17}, () => {18 mb.createImposter({19 });20});

Full Screen

Using AI Code Generation

copy

Full Screen

1const mb = require('mountebank');2mb.start({3}).then(() => {4 console.log('Mountebank started');5}).catch(console.error);6const mb = require('mountebank');7mb.start({8}).then(() => {9 console.log('Mountebank started');10}).catch(console.error);11const mb = require('mountebank');12### `mb.start(options)`13* `port`: the port to listen on (default: 2525)14* `pidfile`: the path to the pidfile (default: `mb.pid`)15* `logfile`: the path to the logfile (default: `mb.log`)16* `ipWhitelist`: the list of IPs allowed to make API calls (default: `['*']`)17* `localOnly`: whether to only allow API calls from localhost (default: `true`)18* `allowInjection`: whether to allow imposters to be injected (default: `false`)19* `noParse`: whether to disable parsing of JSON and XML requests (default: `false`)20* `configfile`: the path to the config file (default: `mb.json`)21* `allowCORS`: whether to allow Cross-Origin Resource Sharing (default: `false`)22* `loglevel`: the level of logging to use (default: `info`)23* `protofile`: the path to the proto file (default: `mb.proto`)24* `mock`: whether to start in mock mode (default: `false`)25* `debug`: whether to start in debug mode (default: `false`)26* `name`: the name of the mountebank server (default: `mb`)27* `version`: the version of the mountebank server (default: `1.0.0`)28* `nodeVersion`: the version of Node.js (default: `process.version`)29* `nodePath`: the path to Node.js (default: `process.execPath`)

Full Screen

Using AI Code Generation

copy

Full Screen

1const mb = require('mountebank');2mb.create({port: 2525, pidfile: 'mb.pid', logfile: 'mb.log', ipWhitelist: ['*']}, function (error) {3 if (error) {4 console.error('Error creating mountebank', error);5 }6 else {7 console.log('mountebank is listening');8 }9});10const mb = require('mountebank');11mb.start({port: 2525, pidfile: 'mb.pid', logfile: 'mb.log', ipWhitelist: ['*']}, function (error) {12 if (error) {13 console.error('Error creating mountebank', error);14 }15 else {16 console.log('mountebank is listening');17 }18});19const mb = require('mountebank');20mb.create({port: 2525, pidfile: 'mb.pid', logfile: 'mb.log', ipWhitelist: ['*']}, function (error) {21 if (error) {22 console.error('Error creating mountebank', error);23 }24 else {25 console.log('mountebank is listening');26 }27});28const imposter = {29 {30 {31 is: {32 headers: {33 },34 body: {35 }36 }37 }38 }39};40mb.createImposter(imposter, function (error, imposter) {41 if (error) {42 console.error('Error creating imposter', error);43 }44 else {45 }46});

Full Screen

Using AI Code Generation

copy

Full Screen

1const mb = require('mountebank');2const fs = require('fs');3const path = require('path');4const { promisify } = require('util');5const writeFile = promisify(fs.writeFile);6const readFile = promisify(fs.readFile);7const mockServerPort = 2525;8const mockServerHost = 'localhost';9const imposters = require('./imposters.json');10const imposterConfig = {11 {12 {13 equals: {14 },15 },16 {17 is: {18 headers: {19 },20 },21 },22 },23};24const createImposters = async () => {25 const response = await mb.post('/imposters', imposterConfig);26 const imposters = await response.json();27 const imposter = imposters[0];28 return imposter;29};30const createImposterConfig = async () => {31 const imposter = await createImposters();32 const imposterConfig = {33 };34 return imposterConfig;35};36const createImposterConfigFile = async () => {37 const imposterConfig = await createImposterConfig();38 const imposters = [imposterConfig];39 const impostersPath = path.join(__dirname, 'imposters.json');40 await writeFile(impostersPath, JSON.stringify(imposters, null, 2));41};42const createImposterConfigFileWithMerge = async () => {43 const imposterConfig = await createImposterConfig();44 const impostersPath = path.join(__dirname, 'imposters.json');45 const file = await readFile(impostersPath);46 const imposters = JSON.parse(file);47 imposters.push(imposterConfig);48 await writeFile(impostersPath, JSON.stringify(imposters, null, 2));49};50const deleteImposterConfigFile = async () => {51 const impostersPath = path.join(__dirname, 'imposters.json');

Full Screen

Using AI Code Generation

copy

Full Screen

1var mb = require('mountebank');2var fs = require('fs');3var path = require('path');4var imposter = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'imposter.json'), 'utf8'));5var options = {6};7mb.create(options, function (error, imposter) {8 if (error) {9 console.log(error);10 } else {11 console.log('imposter created', imposter.port);12 }13});14{15 {16 {17 "is": {18 "headers": {19 },20 "body": {21 }22 }23 }24 {25 "equals": {26 }27 }28 }29}30{"message":"Hello World","status":"success"}31var mb = require('mountebank');32var fs = require('fs');33var path = require('path');34var imposter = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'imposter.json'), 'utf8'));35var options = {36};37mb.create(options, function (error, imposter) {38 if (error) {39 console.log(error);40 } else {41 console.log('imposter created', imposter.port);42 }43});44{45 {46 {47 "is": {48 "headers": {49 },50 "body": {51 }52 }53 }54 {

Full Screen

Using AI Code Generation

copy

Full Screen

1let mb = require('mountebank');2let fs = require('fs');3let path = require('path');4let imposters = JSON.parse(fs.readFileSync(path.join(__dirname, 'imposters.json'), 'utf-8'));5mb.create({ imposters: imposters }, function (error, server) {6 console.log('Server created at %s', server.url);7});

Full Screen

Using AI Code Generation

copy

Full Screen

1var mb = require('mountebank');2var mbHelper = require('mountebank-helper');3var mbHelper = mbHelper.create({mb: mb});4mbHelper.mb.start({port: 2525, pidfile: 'mb.pid', logfile: 'mb.log', ipWhitelist: ['*']})5.then(function (imposter) {6 console.log('Imposter started');7})8.catch(function (error) {9 console.log('Error starting imposter', error);10});

Full Screen

Using AI Code Generation

copy

Full Screen

1const mb = require('mountebank');2const path = require('path');3const config = require('./config.json');4const port = config.port;5const imposters = config.imposters;6const mockserver = mb.create({7});8mockserver.start().then(() => {9 console.log('mountebank server started');10 mockserver.post('/imposters', imposters).then(() => {11 console.log('imposters created');12 });13});14* [Mountebank GitHub](

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run mountebank 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