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 authored and kirovboris committed Dec 18, 2019
1 parent 6a78160 commit 454ff0f
Show file tree
Hide file tree
Showing 23 changed files with 134 additions and 98 deletions.
13 changes: 5 additions & 8 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@ pool: 'BrowserStack agents'

steps:
- bash: |
if [[ $BUILD_SOURCEVERSIONMESSAGE =~ ^\[docs\] ]] || [[ ! -f "appveyor.yml" ]]; then
if [[ $BUILD_SOURCEVERSIONMESSAGE =~ ^\[docs\] ]] || [[ ! -f "appveyor.yml" ]]; then
echo '##vso[task.setvariable variable=isDocCommit]true'
fi
displayName: 'Check commit type'

- task: NodeTool@0
displayName: 'Install Node.js'
condition: not(variables['isDocCommit'])
inputs:
versionSpec: '10.x'
versionSpec: '11.x'

- bash: |
npm install
npm install || npm install || npm install
npm test
displayName: 'Run tests'
condition: not(variables['isDocCommit'])
env:
BROWSER_STACK_USERNAME: $(BROWSER_STACK_USERNAME)
BROWSER_STACK_ACCESS_KEY: $(BROWSER_STACK_ACCESS_KEY)
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
newSession: 'WebDriver:NewSession',
executeScript: 'WebDriver:ExecuteScript',
takeScreenshot: 'WebDriver:TakeScreenshot',
getWindowRect: 'WebDriver:GetWindowRect',
setWindowRect: 'WebDriver:SetWindowRect',
quit: 'Marionette:Quit'
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import Promise from 'pinkie';
import { Socket } from 'net';
import promisifyEvent from 'promisify-event';
import EventEmitter from 'events';
import { writeFile } from '../../../../utils/promisified-functions';
import delay from '../../../../utils/delay';
import { GET_WINDOW_DIMENSIONS_INFO_SCRIPT } from '../../utils/client-functions';
import { writeFile } from '../../../../../utils/promisified-functions';
import delay from '../../../../../utils/delay';
import { GET_WINDOW_DIMENSIONS_INFO_SCRIPT } from '../../../utils/client-functions';
import COMMANDS from './commands';


const CONNECTION_TIMEOUT = 30000;
Expand Down Expand Up @@ -152,7 +153,7 @@ module.exports = class MarionetteClient {
marionetteProtocol: infoPacket.body.marionetteProtocol
};

this.sessionInfo = await this._getResponse({ command: 'newSession' });
this.sessionInfo = await this._getResponse({ command: COMMANDS.newSession });
}

dispose () {
Expand All @@ -161,11 +162,14 @@ module.exports = class MarionetteClient {
}

async executeScript (code) {
return await this._getResponse({ command: 'executeScript', parameters: { script: `return (${code})()` } });
return await this._getResponse({
command: COMMANDS.executeScript,
parameters: { script: `return (${code})()` }
});
}

async takeScreenshot (path) {
const screenshot = await this._getResponse({ command: 'takeScreenshot' });
const screenshot = await this._getResponse({ command: COMMANDS.takeScreenshot });

await writeFile(path, screenshot.value, { encoding: 'base64' });
}
Expand All @@ -175,10 +179,10 @@ module.exports = class MarionetteClient {
let attemptCounter = 0;

while (attemptCounter++ < MAX_RESIZE_RETRY_COUNT && (pageRect.width !== width || pageRect.height !== height)) {
const currentRect = await this._getResponse({ command: 'getWindowRect' });
const currentRect = await this._getResponse({ command: COMMANDS.getWindowRect });

await this._getResponse({
command: 'setWindowRect',
command: COMMANDS.setWindowRect,

parameters: {
x: currentRect.x,
Expand All @@ -193,7 +197,7 @@ module.exports = class MarionetteClient {
}

async quit () {
await this._getResponse({ command: 'quit' });
await this._getResponse({ command: COMMANDS.quit });
}
};

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
2 changes: 1 addition & 1 deletion src/utils/handle-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function formatUnhandledRejectionReason (reason) {
if (reason instanceof Error)
return reason.stack;

return util.inspect(reason);
return util.inspect(reason, { depth: 2, breakLength: Infinity });
}

function onUnhandledRejection (reason) {
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
20 changes: 3 additions & 17 deletions test/functional/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@ testingEnvironments[testingEnvironmentNames.osXDesktopAndMSEdgeBrowsers] = {
osVersion: 'High Sierra',
name: 'firefox',
alias: 'firefox-osx'
},
{
os: 'Windows',
osVersion: '10',
name: 'edge',
alias: 'edge',
}
]
};
Expand All @@ -70,14 +64,6 @@ testingEnvironments[testingEnvironmentNames.mobileBrowsers] = {
retryTestPages: true,

browsers: [
{
realMobile: true,
os: 'android',
osVersion: '7.1',
device: 'Google Pixel',
name: 'Android',
alias: 'android'
},
{
realMobile: true,
os: 'ios',
Expand Down Expand Up @@ -252,8 +238,8 @@ module.exports = {

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

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

browserstackConnectorServicePort: 4000,
browserstackConnectorServicePort: 9200,

browsers: []
};
16 changes: 13 additions & 3 deletions test/functional/fixtures/api/es-next/generic-errors/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ describe('[API] Generic errors', function () {

describe('External assertion library error', function () {
it('Should handle Node built-in assertion lib error', function () {
const NEW_NODE_ASSERTION_MESSAGE = [
const NODE_11_ASSERTION_MESSAGE = [
'AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:',
'+ actual - expected',
'',
'+ \'answer\'',
'- \'42\''
].join(' ');

const NODE_10_ASSERTION_MESSAGE = [
'AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:',
'+ expected - actual',
'',
Expand All @@ -65,8 +73,10 @@ describe('[API] Generic errors', function () {
.catch(function (errs) {
expect(errs[0]).to.contains('> 13 | assert.strictEqual(\'answer\', \'42\');');

if (nodeVersion.major >= 10)
expect(errs[0]).to.contain(NEW_NODE_ASSERTION_MESSAGE);
if (nodeVersion.major >= 11)
expect(errs[0]).to.contain(NODE_11_ASSERTION_MESSAGE);
else if (nodeVersion.major >= 10)
expect(errs[0]).to.contain(NODE_10_ASSERTION_MESSAGE);
else
expect(errs[0]).to.match(OLD_NODE_ASSERTION_MESSAGE_RE);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
<title>PageLoadTimeout (window load long)</title>
</head>
<body>
<img src="./img.png?delay=10000" />
<script>
window.pageOpenedTime = Date.now();

window.addEventListener('load', function () {
window.loadEventRaised = true;
});
</script>
<img src="./img.png?delay=10000" />
<script>
window.pageOpenedTime = Date.now();
</script>
</body>
</html>
Loading

0 comments on commit 454ff0f

Please sign in to comment.