Skip to content

Commit

Permalink
Workaround for location.origin; fix regressions (DevExpress#2978, Dev…
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyBelym committed Oct 23, 2018
1 parent 32a879b commit 877b162
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 56 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"source-map-support": "^0.5.5",
"strip-bom": "^2.0.0",
"testcafe-browser-tools": "1.6.5",
"testcafe-hammerhead": "14.3.0",
"testcafe-hammerhead": "14.3.1",
"testcafe-legacy-api": "3.1.8",
"testcafe-reporter-json": "^2.1.0",
"testcafe-reporter-list": "^2.1.0",
Expand Down
39 changes: 17 additions & 22 deletions src/client/automation/playback/scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,17 @@ export default class ScrollAutomation {
};
}

static _getChildPoint (parentDimensions, childDimensions, offsetX, offsetY) {
static _getChildPoint (parentDimensions, childDimensions, offsets) {
return {
x: childDimensions.left - parentDimensions.left + parentDimensions.scroll.left +
childDimensions.border.left + offsetX,
childDimensions.border.left + offsets.x,
y: childDimensions.top - parentDimensions.top + parentDimensions.scroll.top +
childDimensions.border.top + offsetY
childDimensions.border.top + offsets.y
};
}

_getScrollPosition (parentDimensions, childDimensions, maxScrollMargin, offsetX, offsetY) {
const childPoint = ScrollAutomation._getChildPoint(parentDimensions, childDimensions, offsetX, offsetY);
_getScrollPosition (parentDimensions, childDimensions, offsets, maxScrollMargin) {
const childPoint = ScrollAutomation._getChildPoint(parentDimensions, childDimensions, offsets);
const scrollToPoint = this._getScrollToPoint(parentDimensions, childPoint, maxScrollMargin);
const scrollToFullView = this._getScrollToFullChildView(parentDimensions, childDimensions, maxScrollMargin);

Expand All @@ -165,37 +165,35 @@ export default class ScrollAutomation {
return { left, top };
}

static _getChildPointAfterScroll (parentDimensions, childDimensions, left, top) {
const x = Math.round(childDimensions.left + parentDimensions.scroll.left - left + childDimensions.width / 2);
const y = Math.round(childDimensions.top + parentDimensions.scroll.top - top + childDimensions.height / 2);
static _getChildPointAfterScroll (parentDimensions, childDimensions, currentScroll, offsets) {
const x = Math.round(childDimensions.left + parentDimensions.scroll.left - currentScroll.left + offsets.x);
const y = Math.round(childDimensions.top + parentDimensions.scroll.top - currentScroll.top + offsets.y);

return { x, y };
}

_isChildFullyVisible (parentDimensions, childDimensions, offsetX, offsetY) {
const { x, y } = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, parentDimensions.scroll.left, parentDimensions.scroll.top);
_isChildFullyVisible (parentDimensions, childDimensions, offsets) {
const { x, y } = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, parentDimensions.scroll, offsets);
const zeroMargin = { left: 0, top: 0 };

const { left, top } = this._getScrollPosition(parentDimensions, childDimensions, {
left: 0,
top: 0
}, offsetX, offsetY);
const { left, top } = this._getScrollPosition(parentDimensions, childDimensions, offsets, zeroMargin);

return !this._isTargetElementObscuredInPoint(x, y) &&
left === parentDimensions.scroll.left && top === parentDimensions.scroll.top;
}

_scrollToChild (parent, child, { offsetX, offsetY }) {
_scrollToChild (parent, child, offsets) {
const parentDimensions = positionUtils.getClientDimensions(parent);
const childDimensions = positionUtils.getClientDimensions(child);
const windowWidth = styleUtils.getInnerWidth(window);
const windowHeight = styleUtils.getInnerHeight(window);
let scrollPos = parentDimensions.scroll;
let needScroll = !this._isChildFullyVisible(parentDimensions, childDimensions, offsetX, offsetY);
let needScroll = !this._isChildFullyVisible(parentDimensions, childDimensions, offsets);

while (needScroll) {
scrollPos = this._getScrollPosition(parentDimensions, childDimensions, this.maxScrollMargin, offsetX, offsetY);
scrollPos = this._getScrollPosition(parentDimensions, childDimensions, offsets, this.maxScrollMargin);

const { x, y } = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, scrollPos.left, scrollPos.top);
const { x, y } = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, scrollPos, offsets);
const isTargetObscured = this._isTargetElementObscuredInPoint(x, y);

this.maxScrollMargin.left += SCROLL_MARGIN_INCREASE_STEP;
Expand Down Expand Up @@ -235,10 +233,7 @@ export default class ScrollAutomation {

const scrollParentsPromise = promiseUtils.times(parents.length, i => {
return this
._scrollToChild(parents[i], currentChild, {
offsetX: currentOffsetX,
offsetY: currentOffsetY
})
._scrollToChild(parents[i], currentChild, { x: currentOffsetX, y: currentOffsetY })
.then(() => {
childDimensions = positionUtils.getClientDimensions(currentChild);
parentDimensions = positionUtils.getClientDimensions(parents[i]);
Expand Down
4 changes: 4 additions & 0 deletions src/client/test-run/index.js.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
var origin = location.origin;
// NOTE: location.origin doesn't exist in IE11 on Windows 10.10240 LTSB
if (!origin)
origin = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
var testRunId = {{{testRunId}}};
var browserId = {{{browserId}}};
var selectorTimeout = {{{selectorTimeout}}};
Expand Down
2 changes: 1 addition & 1 deletion src/errors/render-forbidden-chars-list.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default function (forbiddenCharsList) {
return forbiddenCharsList.map(charInfo => `\t"${charInfo.char}" at index ${charInfo.index}\n`).join('');
return forbiddenCharsList.map(charInfo => `\t"${charInfo.chars}" at index ${charInfo.index}\n`).join('');
}
21 changes: 11 additions & 10 deletions src/utils/check-file-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@ import { win as isWin } from 'os-family';
import sanitizeFilename from 'sanitize-filename';


const SAFE_CHAR = '_';
const ALLOWED_CHARS_LIST = [path.win32.sep, path.posix.sep, '.', '..'];


function correctForbiddenCharsList (forbiddenCharsList, filePath) {
const isWinAbsolutePath = isWin && path.isAbsolute(filePath);
const hasDriveSeparatorInList = forbiddenCharsList.length && forbiddenCharsList[0].char === ':' && forbiddenCharsList[0].index === 1;
const hasDriveSeparatorInList = forbiddenCharsList.length && forbiddenCharsList[0].chars === ':' && forbiddenCharsList[0].index === 1;

if (isWinAbsolutePath && hasDriveSeparatorInList)
forbiddenCharsList.shift();
}

function addForbiddenCharToList (forbiddenCharsList, forbiddenCharInfo) {
const { char } = forbiddenCharInfo;
function addForbiddenCharsToList (forbiddenCharsList, forbiddenCharsInfo) {
const { chars } = forbiddenCharsInfo;

if (char === path.win32.sep || char === path.posix.sep)
return '';
if (!ALLOWED_CHARS_LIST.includes(chars))
forbiddenCharsList.push(forbiddenCharsInfo);

forbiddenCharsList.push(forbiddenCharInfo);

return '';
return SAFE_CHAR.repeat(chars.length);
}


export default function (filePath) {
const forbiddenCharsList = [];

sanitizeFilename(filePath, {
replacement: (char, index) => addForbiddenCharToList(forbiddenCharsList, { char, index })
replacement: (chars, index) => addForbiddenCharsToList(forbiddenCharsList, { chars, index })
});

correctForbiddenCharsList(forbiddenCharsList, filePath);
Expand Down
22 changes: 10 additions & 12 deletions test/client/fixtures/automation/regression-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,33 +339,31 @@ $(document).ready(function () {
});
});

asyncTest('B237672 - TesCafe throw exception "Access is denied" after trying to get content of iframe in IE browsers', function () {
let clicked = false;
asyncTest('B237672 - TesCafe should not throw an exception "Access is denied" on accessing to a content of the cross-domain iframe', function () {
let result = false;

const $iframe = $('<iframe></iframe>')
.width(500)
.height(500)
.attr('src', 'http://www.cross.domain.com')
.addClass(TEST_ELEMENT_CLASS)
.click(function () {
clicked = true;
});
.addClass(TEST_ELEMENT_CLASS);

window.QUnitGlobals.waitForIframe($iframe[0]).then(function () {
try {
//NOTE: for not ie
const iframeBody = $iframe[0].contentWindow.document;
const iframeDocument = $iframe[0].contentWindow.document;

nativeMethods.addEventListener.call(iframeBody, 'click', function () {
clicked = true;
nativeMethods.addEventListener.call(iframeDocument, 'click', function () {
throw new Error('Click handler on an iframe should not be called');
});

result = true;
}
catch (e) {
// do nothing
result = false;
}

runClickAutomation($iframe[0], {}, function () {
ok(clicked, 'click was raised');
ok(result);
startNext();
});
});
Expand Down
8 changes: 4 additions & 4 deletions test/functional/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ testingEnvironments[testingEnvironmentNames.mobileBrowsers] = {
{
realMobile: true,
os: 'android',
osVersion: '7.1',
osVersion: '8.0',
device: 'Google Pixel',
name: 'Android',
alias: 'android'
Expand Down Expand Up @@ -248,8 +248,8 @@ module.exports = {

testCafe: {
hostname: hostname,
port1: 2000,
port2: 2001
port1: 9000,
port2: 9001
},

site: {
Expand All @@ -264,7 +264,7 @@ module.exports = {
}
},

browserstackConnectorServicePort: 4000,
browserstackConnectorServicePort: 9200,

browsers: []
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
position: absolute;
left: 500px;
top: 500px;
width: 20px;
height: 20px;
width: 200px;
height: 200px;
background-color: red;
}

#target2 {
position: absolute;
left: 2500px;
top: 2500px;
width: 20px;
height: 20px;
width: 200px;
height: 200px;
background-color: blue;
}

Expand Down
8 changes: 8 additions & 0 deletions test/functional/fixtures/regression/gh-1057/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ describe('[Regression](GH-1057) - hidden by fixed parent', function () {
skip: 'iphone,ipad,android'
});
});

it('The target element should not be under the element with position:fixed after scroll when using custom offsets', function () {
return runTests('testcafe-fixtures/hiddenByFixedParent.js', 'gh-1057 with custom offsets', {
// NOTE: https://github.com/DevExpress/testcafe/issues/1237
// TODO: Android disabled because of https://github.com/DevExpress/testcafe/issues/1492
skip: 'iphone,ipad,android'
});
});
});

describe('[Regression](GH-1057) - hidden by fixed ancestor', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ test('gh-1057', async t => {
.click('#target1')
.expect(targetsClicked()).ok();
});

test('gh-1057 with custom offsets', async t => {
// NOTE: scrolling has issues in iOS Simulator https://github.com/DevExpress/testcafe/issues/1237
await t
.click('#target2', { offsetX: -1, offsetY: -1 })
.click('#target1', { offsetX: 1, offsetY: 1 })
.expect(targetsClicked()).ok();
});
2 changes: 1 addition & 1 deletion test/functional/fixtures/regression/gh-2067/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe('[Regression](GH-2067) - Radio button navigation by keyboard', function
});

it('nonamed - chrome', function () {
return runTests('testcafe-fixtures/index.js', 'nonamed - chrome', { only: ['chrome', 'chrome-osx', 'android'] });
return runTests('testcafe-fixtures/index.js', 'nonamed - chrome', { only: ['chrome', 'chrome-osx'] });
});

it('nonamed - ie, firefox', function () {
Expand Down
16 changes: 16 additions & 0 deletions test/server/runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,22 @@ describe('Runner', () => {
'screenshots path pattern:\n \t":" at index 7\n');
});
});

it('Should allow to use relative paths in the screenshots base path and path patterns', () => {
const storedRunTaskFn = runner._runTask;

runner._runTask = function () {
runner._runTask = storedRunTaskFn;

return Promise.resolve({});
};

return runner
.browsers(connection)
.screenshots('..', false, '${BROWSER}/./${TEST}')
.src('test/server/data/test-suites/basic/testfile2.js')
.run();
});
});

describe('.src()', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/server/test-run-error-formatting-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ describe('Error formatting', () => {
});

it('Should format "forbiddenCharactersInScreenshotPathError"', () => {
assertErrorMessage('forbidden-characters-in-screenshot-path-error', new ForbiddenCharactersInScreenshotPathError('/root/bla:bla', [{ char: ':', index: 9 }]));
assertErrorMessage('forbidden-characters-in-screenshot-path-error', new ForbiddenCharactersInScreenshotPathError('/root/bla:bla', [{ chars: ':', index: 9 }]));
});

it('Should format "invalidElementScreenshotDimensionsError"', () => {
Expand Down

0 comments on commit 877b162

Please sign in to comment.