Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions autotests/pageObjects/pages/Search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {MobilePage} from 'autotests/pageObjects';
import {Input} from 'autotests/pageObjects/components';
import {Search as SearchRoute} from 'autotests/routes/pageRoutes';
import {setReadonlyProperty} from 'e2ed/utils';

Expand All @@ -16,6 +17,8 @@ export class Search extends MobilePage<CustomPageParams> {
*/
readonly mobileDevice = 'iphone' as const;

readonly searchInput: Input = new Input('q');

/**
* The search query of the page.
*/
Expand Down
68 changes: 68 additions & 0 deletions autotests/tests/main/viewport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {test} from 'autotests';
import {Search} from 'autotests/pageObjects/pages';
import {expect} from 'e2ed';
import {navigateToPage, scroll} from 'e2ed/actions';
import {isSelectorEntirelyInViewport, isSelectorInViewport} from 'e2ed/utils';

test(
'isSelectorInViewport, isSelectorEntirelyInViewport and expect().toBeInViewport',
{meta: {testId: '24'}},
async () => {
const scrollValueForPartialInViewport = 50;
const scrollValueForNotInViewport = 500;

const searchQuery = 'foo';
const searchPage = await navigateToPage(Search, {searchQuery});

const searchInputSelector = searchPage.searchInput.input;

await expect(
isSelectorInViewport(searchInputSelector),
'isSelectorInViewport: searchInput is in viewport after page load',
).ok();

await expect(
isSelectorEntirelyInViewport(searchInputSelector),
'isSelectorEntirelyInViewport: searchInput is entirely in viewport after page load',
).ok();

await expect(
searchInputSelector,
'toBeInViewport: searchInput is in viewport after page load',
).toBeInViewport();

await expect(
searchInputSelector,
'toBeInViewport with ratio 1: searchInput is entirely in viewport after page load',
).toBeInViewport({ratio: 1});

await scroll(0, scrollValueForPartialInViewport);

await expect(
isSelectorInViewport(searchInputSelector),
'isSelectorInViewport: searchInput is in viewport after smaill scroll',
).ok();

await expect(
isSelectorEntirelyInViewport(searchInputSelector),
'isSelectorEntirelyInViewport: searchInput is not entirely in viewport after small scroll',
).notOk();

await expect(
searchInputSelector,
'toBeInViewport with ratio 0.1: searchInput is not entirely in viewport after small scroll',
).toBeInViewport({ratio: 0.1});

await scroll(0, scrollValueForNotInViewport);

await expect(
isSelectorInViewport(searchInputSelector),
'isSelectorInViewport: searchInput is not in viewport after big scroll',
).notOk();

await expect(
isSelectorEntirelyInViewport(searchInputSelector),
'isSelectorEntirelyInViewport: searchInput is not entirely in viewport after big scroll',
).notOk();
},
);
4 changes: 2 additions & 2 deletions bin/makeExecutable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ IFS=$'\n\t'

files=("$@")

for file in ${files[*]}; do
sed -i '1s|^|#!/usr/bin/env node\n\n|' $file && chmod +x $file
for file in "${files[@]}"; do
printf '#!/usr/bin/env node\n\n' | cat - "$file" > "$file.tmp" && mv "$file.tmp" "$file" && chmod +x "$file"
done
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"prebuild": "npm run build:clear",
"build": "tsc; echo 'Compilation completed'",
"postbuild": "npm run build:rename && npm run build:remove && npm run build:copy && npm run build:init",
"prebuild:rename": "mkdir --parents ./build/node_modules",
"prebuild:rename": "mkdir -p ./build/node_modules",
"build:rename": "mv ./build/src ./build/node_modules/e2ed",
"build:remove": "npm run build:remove:empty-d-ts && npm run build:remove:types-js",
"build:remove:empty-d-ts": "find ./build/node_modules/e2ed/ -name *.d.ts -size 11c -exec rm {} \\;",
Expand Down
17 changes: 11 additions & 6 deletions src/utils/viewport/isSelectorEntirelyInViewport.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import type {Selector} from '../../types/internal';

import {expect as playwrightExpect} from '@playwright/test';

/**
* Returns `true`, if the selector is entirely in the viewport
* (all selector points are in the viewport), and `false` otherwise.
*/
export const isSelectorEntirelyInViewport = async (selector: Selector): Promise<boolean> => {
const htmlElementSelector = selector.createSelector('html');

const {height: clientHeight, width: clientWidth} = await htmlElementSelector.boundingClientRect;

const {bottom, left, right, top} = await selector.boundingClientRect;
try {
await playwrightExpect(selector.getPlaywrightLocator()).toBeInViewport({
ratio: 1,
timeout: 1,
});

return top >= 0 && bottom <= clientHeight && left >= 0 && right <= clientWidth;
return true;
} catch {
return false;
}
};
14 changes: 8 additions & 6 deletions src/utils/viewport/isSelectorInViewport.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import type {Selector} from '../../types/internal';

import {expect as playwrightExpect} from '@playwright/test';

/**
* Returns `true`, if the selector is in the viewport
* (intersects with the viewport at least in one point), and `false` otherwise.
*/
export const isSelectorInViewport = async (selector: Selector): Promise<boolean> => {
const htmlElementSelector = selector.createSelector('html');

const {height: clientHeight, width: clientWidth} = await htmlElementSelector.boundingClientRect;

const {bottom, left, right, top} = await selector.boundingClientRect;
try {
await playwrightExpect(selector.getPlaywrightLocator()).toBeInViewport({timeout: 1});

return top < clientHeight && bottom > 0 && left < clientWidth && right > 0;
return true;
} catch {
return false;
}
};