Skip to content

Commit

Permalink
Merge branch 'master' into refactor/src/client/core/barriers
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksey28 authored Sep 11, 2023
2 parents 1eb4a81 + 74306a2 commit e977fe5
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 101 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Your complete test code (or attach your test files)

* testcafe version: <!-- run `testcafe -v` -->
* node.js version: <!-- run `node -v` -->
* command-line arguments: <!-- example: "testcafe ie,chrome -e test.js" -->
* browser name and version: <!-- example: IE 11, Chrome 69, Firefox 100, etc. -->
* command-line arguments: <!-- example: "testcafe edge,chrome -e test.js" -->
* browser name and version: <!-- example: Edge 116, Chrome 116, Firefox 117, etc. -->
* platform and version: <!-- example: "macOS 10.14, Windows, Linux Ubuntu 18.04.1, iOS 12 -->
* other: <!-- any notes you consider important -->
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ body:
attributes:
label: Command-line arguments
description: >
Example: testcafe ie,chrome -e test.js
Example: testcafe edge,chrome -e test.js
validations:
required: true

Expand All @@ -138,7 +138,7 @@ body:
attributes:
label: Browser name(s) and version(s)
description: >
Example: IE 11, Chrome 69, Firefox 100, etc.
Example: Edge 116, Chrome 116, Firefox 117, etc.
validations:
required: false

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/handle-stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
close-pr-message: "We're closing this pull request after a prolonged period of inactivity. If it is still relevant, please ask for this pull request to be reopened. Thank you."
stale-issue-label: "STATE: Stale"
stale-pr-label: "STATE: Stale"
days-before-stale: 365
days-before-stale: 180
days-before-close: 10
exempt-issue-labels: "AREA: docs,FREQUENCY: critical,FREQUENCY: level 2,HELP WANTED,!IMPORTANT!,STATE: Need clarification,STATE: Need response,STATE: won't fix,support center"
exempt-pr-labels: "AREA: docs,FREQUENCY: critical,FREQUENCY: level 2,HELP WANTED,!IMPORTANT!,STATE: Need clarification,STATE: Need response,STATE: won't fix,support center"
exempt-issue-labels: "AREA: docs,FREQUENCY: critical,FREQUENCY: level 2,STATE: Need clarification,STATE: Need response,STATE: won't fix,support center"
exempt-pr-labels: "AREA: docs,FREQUENCY: critical,FREQUENCY: level 2,STATE: Need clarification,STATE: Need response,STATE: won't fix,support center"
2 changes: 1 addition & 1 deletion gulp/constants/client-test-settings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { assignIn } = require('lodash');

const CLIENT_TEST_LOCAL_BROWSERS_ALIASES = ['ie', 'edge', 'chrome', 'firefox', 'safari'];
const CLIENT_TEST_LOCAL_BROWSERS_ALIASES = ['edge', 'chrome', 'firefox', 'safari'];

const CLIENT_TESTS_PATH = 'test/client/fixtures';
const CLIENT_TESTS_LEGACY_PATH = 'test/client/legacy-fixtures';
Expand Down
8 changes: 6 additions & 2 deletions src/api/request-hooks/request-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class RequestLoggerImplementation extends RequestHook {
throw new APIError('RequestLogger', RUNTIME_ERRORS.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.');
}

private static _getInternalRequestKey ({ requestId, sessionId }: any): string {
return `${sessionId}:${requestId}`;
}

public async onRequest (event: RequestEvent): Promise<void> {
const loggedReq: LoggedRequest = {
id: event._requestInfo.requestId,
Expand All @@ -98,11 +102,11 @@ class RequestLoggerImplementation extends RequestHook {
if (this._options.logRequestBody)
loggedReq.request.body = this._options.stringifyRequestBody ? event._requestInfo.body.toString() : event._requestInfo.body;

this._internalRequests[loggedReq.id] = loggedReq;
this._internalRequests[RequestLoggerImplementation._getInternalRequestKey(event._requestInfo)] = loggedReq;
}

public async onResponse (event: ResponseEvent): Promise<void> {
const loggedReq = this._internalRequests[event.requestId];
const loggedReq = this._internalRequests[RequestLoggerImplementation._getInternalRequestKey(event)];

// NOTE: If the 'clear' method is called during a long running request,
// we should not save a response part - request part has been already removed.
Expand Down
31 changes: 6 additions & 25 deletions src/client/automation/playback/click/browser-click-strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import hammerhead from '../../deps/hammerhead';
import testCafeCore from '../../deps/testcafe-core';
import { focusAndSetSelection } from '../../utils/utils';
import nextTick from '../../../core/utils/next-tick';
import createClickCommand from './click-command';

import { MouseEventArgs } from '../../visible-element-automation';
Expand Down Expand Up @@ -82,10 +81,9 @@ export class MouseClickStrategy {

this.activeElementBeforeMouseDown = activeElement;

// NOTE: In WebKit and IE, the mousedown event opens the select element's dropdown;
// NOTE: In WebKit, the mousedown event opens the select element's dropdown;
// therefore, we should prevent mousedown and hide the dropdown (B236416).
const needCloseSelectDropDown = (browserUtils.isWebKit || browserUtils.isIE) &&
domUtils.isSelectElement(this.mouseDownElement);
const needCloseSelectDropDown = browserUtils.isWebKit && domUtils.isSelectElement(this.mouseDownElement);

if (needCloseSelectDropDown)
this._bindMousedownHandler();
Expand Down Expand Up @@ -115,8 +113,7 @@ export class MouseClickStrategy {
listeners.removeInternalEventBeforeListener(window, ['mouseup'], getTimeStamp);
};

if (!browserUtils.isIE)
listeners.addInternalEventBeforeListener(window, ['mouseup'], getTimeStamp);
listeners.addInternalEventBeforeListener(window, ['mouseup'], getTimeStamp);

if (!this._isTouchEventWasCancelled())
eventSimulator.mouseup(element, eventArgs.options);
Expand Down Expand Up @@ -174,21 +171,8 @@ export class MouseClickStrategy {
return;
}

if (browserUtils.isIE && browserUtils.version < 12) {
// NOTE: In whatever way an element is blurred from the client script, the
// blur event is raised asynchronously in IE (in MSEdge focus/blur is sync)
nextTick()
.then(() => {
if (!this.eventState.blurRaised)
eventSimulator.blur(element);

resolve();
});
}
else {
eventSimulator.blur(element);
resolve();
}
eventSimulator.blur(element);
resolve();
});
}

Expand All @@ -201,10 +185,7 @@ export class MouseClickStrategy {
// element, a selection position may be calculated incorrectly (by using the caretPos option).
const elementForFocus = domUtils.isContentEditableElement(this.element) ? this.element : eventArgs.element;

// NOTE: IE doesn't perform focus if active element has been changed while executing mousedown
const simulateFocus = !browserUtils.isIE || this.activeElementBeforeMouseDown === domUtils.getActiveElement();

return focusAndSetSelection(elementForFocus, simulateFocus, this.caretPos);
return focusAndSetSelection(elementForFocus, true, this.caretPos);
}

private _raiseTouchEvents (eventArgs: MouseEventArgs): void {
Expand Down
20 changes: 3 additions & 17 deletions src/client/automation/playback/click/select-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ export default class SelectChildClickAutomation {

_calculateEventArguments () {
const childElement = this.optionListExpanded ? selectController.getEmulatedChildElement(this.element) : this.element;
const parentSelectSize = styleUtils.getSelectElementSize(this.parentSelect) > 1;

return {
options: this.modifiers,
element: browserUtils.isIE && parentSelectSize ? this.parentSelect : childElement,
element: childElement,
};
}

Expand Down Expand Up @@ -123,12 +122,6 @@ export default class SelectChildClickAutomation {
return this._focus();
}

if (browserUtils.isIE) {
eventSimulator.mousedown(this.eventsArgs.element, this.eventsArgs.options);

return this._focus();
}

// NOTE: In Chrome, document.activeElement is 'select' after mousedown. But we need to
// raise blur and change the event for a previously active element during focus raising.
// That's why we should change the event order and raise focus before mousedown.
Expand All @@ -150,22 +143,15 @@ export default class SelectChildClickAutomation {
}

_mouseup () {
const elementForMouseupEvent = browserUtils.isIE ? this.parentSelect : this.eventsArgs.element;

eventSimulator.mouseup(elementForMouseupEvent, this.eventsArgs.options);

if (browserUtils.isIE && this.clickCausesChange)
this.parentSelect.selectedIndex = this.childIndex;
eventSimulator.mouseup(this.eventsArgs.element, this.eventsArgs.options);

const simulateInputEventOnValueChange = browserUtils.isFirefox || browserUtils.isSafari ||
browserUtils.isChrome && browserUtils.version >= 53;

const simulateChangeEventOnValueChange = simulateInputEventOnValueChange || browserUtils.isIE;

if (simulateInputEventOnValueChange && this.clickCausesChange)
eventSimulator.input(this.parentSelect);

if (simulateChangeEventOnValueChange && this.clickCausesChange)
if (simulateInputEventOnValueChange && this.clickCausesChange)
eventSimulator.change(this.parentSelect);

return Promise.resolve();
Expand Down
18 changes: 1 addition & 17 deletions src/client/automation/playback/move/event-sequence/base.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import hammerhead from '../../../deps/hammerhead';
import { domUtils } from '../../../deps/testcafe-core';

const browserUtils = hammerhead.utils.browser;

export default class MoveEventSequenceBase {
constructor ({ moveEvent }) {
Expand Down Expand Up @@ -31,16 +29,6 @@ export default class MoveEventSequenceBase {
}

run (currentElement, prevElement, options, dragElement, dragDataStore) {
// NOTE: if last hovered element was in an iframe that has been removed, IE
// raises an exception when we try to compare it with the current element
const prevElementInDocument = prevElement && domUtils.isElementInDocument(prevElement);

const prevElementInRemovedIframe = prevElement && domUtils.isElementInIframe(prevElement) &&
!domUtils.getIframeByElement(prevElement);

if (!prevElementInDocument || prevElementInRemovedIframe)
prevElement = null;

const elementChanged = currentElement !== prevElement;
const commonAncestor = elementChanged ? domUtils.getCommonAncestor(currentElement, prevElement) : null;

Expand All @@ -49,14 +37,10 @@ export default class MoveEventSequenceBase {
if (elementChanged && !!prevElement)
this.leaveElement(currentElement, prevElement, commonAncestor, options);

if (browserUtils.isIE)
this.move(currentElement, options);

if (elementChanged && domUtils.isElementInDocument(currentElement))
this.enterElement(currentElement, prevElement, commonAncestor, options);

if (!browserUtils.isIE)
this.move(currentElement, options);
this.move(currentElement, options);

this.dragAndDrop(dragElement, currentElement, prevElement, options, dragDataStore);
this.teardown(currentElement, options, prevElement);
Expand Down
27 changes: 9 additions & 18 deletions src/client/automation/playback/press/key-press-simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,18 @@ export default class KeyPressSimulator {
const isActiveElementEditable = domUtils.isEditableElement(element);
const isStoredElementEditable = domUtils.isEditableElement(this.storedActiveElement);

// Unnecessary typing happens if an element was changed after the keydown/keypress event (T210448)
// In IE, this error may occur when we try to determine if the removed element is in an iframe
try {
if (elementChanged) {
const isActiveElementInIframe = domUtils.isElementInIframe(element);
const isStoredElementInIframe = domUtils.isElementInIframe(this.storedActiveElement);

const shouldTypeInWebKit = isActiveElementInIframe === isStoredElementInIframe || isStoredElementEditable;

shouldType = (!browserUtils.isFirefox || isStoredElementEditable) &&
(!browserUtils.isWebKit || shouldTypeInWebKit);
}
}
/*eslint-disable no-empty */
catch (err) {
}
/*eslint-disable no-empty */
if (elementChanged) {
const isActiveElementInIframe = domUtils.isElementInIframe(element);
const isStoredElementInIframe = domUtils.isElementInIframe(this.storedActiveElement);

const shouldTypeInWebKit = isActiveElementInIframe === isStoredElementInIframe || isStoredElementEditable;

shouldType = (!browserUtils.isFirefox || isStoredElementEditable) &&
(!browserUtils.isWebKit || shouldTypeInWebKit);
}

if (shouldType) {
if (!browserUtils.isIE && elementChanged && isStoredElementEditable && isActiveElementEditable)
if (elementChanged && isStoredElementEditable && isActiveElementEditable)
elementForTyping = this.storedActiveElement;

typeText(elementForTyping, char);
Expand Down
3 changes: 1 addition & 2 deletions src/client/automation/playback/press/shortcuts.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,7 @@ function enter (element) {

//submit form on enter pressed
if (domUtils.isInputElement(element)) {
if (!browserUtils.isIE)
elementEditingWatcher.processElementChanging(element);
elementEditingWatcher.processElementChanging(element);

const form = domUtils.getParents(element, 'form')[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default class RequestPausedEventBasedEventFactory extends BaseRequestHook
statusCode: this._event.responseStatusCode || StatusCodes.OK,
headers: convertToOutgoingHttpHeaders(this._event.responseHeaders),
body: this._responseBody,
sessionId: '',
sessionId: this._sessionId,
requestId: this._event.requestId,
isSameOriginPolicyFailed: false,
});
Expand Down
5 changes: 1 addition & 4 deletions test/functional/assertion-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,7 @@ exports.checkUserAgent = function (errs, alias) {
const parsedUA = parseUserAgent(errs[0]);
const prettyUA = parsedUA.prettyUserAgent.toLowerCase();

// NOTE: the "ie" alias corresponds to the "internet explorer" lowered part of a compact user agent string (GH-481)
const expectedBrowserName = alias === 'ie' ? 'internet explorer' : alias;

expect(prettyUA.indexOf(expectedBrowserName)).eql(0, prettyUA + ' doesn\'t start with "' + expectedBrowserName + '"');
expect(prettyUA.indexOf(alias)).eql(0, prettyUA + ' doesn\'t start with "' + alias + '"');
};

exports.SCREENSHOTS_PATH = SCREENSHOTS_PATH;
Expand Down
7 changes: 0 additions & 7 deletions test/functional/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const browserProviderNames = {

const testingEnvironmentNames = {
mobileBrowsers: 'mobile-browsers',
localBrowsersIE: 'local-browsers-ie',
localBrowsersChromeFirefox: 'local-browsers-chrome-firefox',
localBrowsers: 'local-browsers',
localChrome: 'local-chrome',
Expand Down Expand Up @@ -52,12 +51,6 @@ testingEnvironments[testingEnvironmentNames.localBrowsers] = {
browserName: 'chrome',
alias: 'chrome',
},
{
platform: 'Windows 10',
browserName: 'ie',
version: '11.0',
alias: 'ie',
},
{
platform: 'Windows 10',
browserName: 'firefox',
Expand Down
19 changes: 19 additions & 0 deletions test/functional/fixtures/regression/gh-7977/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>gh-7977</title>
</head>
<body>
<button>click me</button>
<script>
function handler () {
for (let i = 0; i < 100; i++) {
fetch('http://localhost:3000/api/data');
}
}

document.querySelector('button').addEventListener('click', handler);
</script>
</body>
</html>
30 changes: 30 additions & 0 deletions test/functional/fixtures/regression/gh-7977/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const createTestCafe = require('../../../../../lib');
const { onlyInNativeAutomation } = require('../../../utils/skip-in');
const path = require('path');
const expect = require('chai').expect;

const EXPECTED_REQUEST_COUNT = 300;

let testcafe = null;

describe('[Regression](GH-7977)', function () {
onlyInNativeAutomation('Should log all concurrent requests', function () {
return createTestCafe('127.0.0.1', 1335, 1336)
.then(tc => {
testcafe = tc;
})
.then(() => {
return testcafe.createRunner()
.browsers(`chrome:headless`)
.concurrency(3)
.src(path.join(__dirname, './testcafe-fixtures/index.js'))
.run();
})
.then(() => {
return testcafe.close();
})
.then(() => {
expect(require('./testcafe-fixtures/requestCounter').get()).eql(EXPECTED_REQUEST_COUNT);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RequestLogger } from 'testcafe';

const logger = new RequestLogger(/api\/data/, {
logResponseBody: true,
logRequestHeaders: true,
stringifyResponseBody: true,
});

fixture `Concurrent request loggers`
.page `http://localhost:3000/fixtures/regression/gh-7977/pages/index.html`
.requestHooks(logger);

for (let i = 0; i < 3; i++) {
test(`send multiple requests - ${i}`, async t => {
await t.click('button');

require('./requestCounter').add(logger.requests.filter(r => !!r.response.body).length);
});
}


Loading

0 comments on commit e977fe5

Please sign in to comment.