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
10 changes: 10 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ jobs:
sudo apt-get update --allow-releaseinfo-change
- name: Install browsers and deps
run: npx playwright install && npx playwright install-deps
- name: Start mock server
run: nohup npm run mock-server:start &
- name: Wait for mock server
run: |
for i in {1..20}; do
curl -sSf http://localhost:3001/api/users && break
sleep 1
done
- name: check
run: './bin/codecept.js check -c test/acceptance/codecept.Playwright.js'
- name: start a server
Expand All @@ -58,3 +66,5 @@ jobs:
run: 'BROWSER=webkit node ./bin/codecept.js run -c test/acceptance/codecept.Playwright.js --grep @Playwright --debug'
- name: run chromium unit tests
run: ./node_modules/.bin/mocha test/helper/Playwright_test.js --timeout 5000
- name: Stop mock server
run: npm run mock-server:stop
10 changes: 10 additions & 0 deletions .github/workflows/puppeteer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ jobs:
npm i --force && npm i puppeteer --force
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
- name: Start mock server
run: nohup npm run mock-server:start &
- name: Wait for mock server
run: |
for i in {1..20}; do
curl -sSf http://localhost:3001/api/users && break
sleep 1
done
- name: start a server
run: 'php -S 127.0.0.1:8000 -t test/data/app &'
- uses: browser-actions/setup-chrome@v2
Expand All @@ -43,3 +51,5 @@ jobs:
run: './bin/codecept.js run-workers 2 -c test/acceptance/codecept.Puppeteer.js --grep @Puppeteer --debug'
- name: run unit tests
run: ./node_modules/.bin/mocha test/helper/Puppeteer_test.js
- name: Stop mock server
run: npm run mock-server:stop
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ jobs:
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
- name: Start mock server
run: nohup npm run mock-server:start &
- name: Wait for mock server
run: |
for i in {1..20}; do
curl -sSf http://localhost:3001/api/users && break
sleep 1
done
- run: npm run test:unit
- name: Stop mock server
run: npm run mock-server:stop

runner-tests:
name: Runner tests
Expand All @@ -47,6 +57,16 @@ jobs:
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
- name: Start mock server
run: nohup npm run mock-server:start &
- name: Wait for mock server
run: |
for i in {1..20}; do
curl -sSf http://localhost:3001/api/users && break
sleep 1
done
- run: npm run test:runner
- name: Stop mock server
run: npm run mock-server:stop
# Note: Runner tests are mocha-based, so sharding doesn't apply here.
# For CodeceptJS sharding examples, see sharding-demo.yml workflow.
10 changes: 10 additions & 0 deletions .github/workflows/webdriver.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ jobs:
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: true
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
- name: Start mock server
run: nohup npm run mock-server:start &
- name: Wait for mock server
run: |
for i in {1..20}; do
curl -sSf http://localhost:3001/api/users && break
sleep 1
done
- name: start a server
run: 'php -S 127.0.0.1:8000 -t test/data/app &'
- name: check
Expand All @@ -44,3 +52,5 @@ jobs:
run: ./node_modules/.bin/mocha test/helper/WebDriver_test.js --exit
- name: run tests
run: './bin/codecept.js run -c test/acceptance/codecept.WebDriver.js --grep @WebDriver --debug'
- name: Stop mock server
run: npm run mock-server:stop
8 changes: 4 additions & 4 deletions lib/helper/JSONResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ class JSONResponse extends Helper {
if (!this.helpers[this.options.requestHelper]) {
throw new Error(`Error setting JSONResponse, helper ${this.options.requestHelper} is not enabled in config, helpers: ${Object.keys(this.helpers)}`)
}
const origOnResponse = this.helpers[this.options.requestHelper].config.onResponse;
const origOnResponse = this.helpers[this.options.requestHelper].config.onResponse
this.helpers[this.options.requestHelper].config.onResponse = response => {
this.response = response;
if (typeof origOnResponse === 'function') origOnResponse(response);
};
this.response = response
if (typeof origOnResponse === 'function') origOnResponse(response)
}
}

_before() {
Expand Down
6 changes: 3 additions & 3 deletions lib/helper/WebDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ class WebDriver extends Helper {
* {{ react }}
*/
async click(locator, context = null) {
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const locateFn = prepareLocateFn.call(this, context)

const res = await findClickable.call(this, locator, locateFn)
Expand Down Expand Up @@ -1217,7 +1217,7 @@ class WebDriver extends Helper {
* {{> checkOption }}
*/
async checkOption(field, context = null) {
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const locateFn = prepareLocateFn.call(this, context)

const res = await findCheckable.call(this, field, locateFn)
Expand All @@ -1237,7 +1237,7 @@ class WebDriver extends Helper {
* {{> uncheckOption }}
*/
async uncheckOption(field, context = null) {
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick'
const locateFn = prepareLocateFn.call(this, context)

const res = await findCheckable.call(this, field, locateFn)
Expand Down
4 changes: 2 additions & 2 deletions lib/listener/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ module.exports = function () {
return currentHook.steps.push(step)
}
if (!currentTest || !currentTest.steps) return

// Check if we're in a session that should be excluded from main test steps
const currentSessionId = recorder.getCurrentSessionId()
if (currentSessionId && EXCLUDED_SESSIONS.includes(currentSessionId)) {
// Skip adding this step to the main test steps
return
}

currentTest.steps.push(step)
})

Expand Down
2 changes: 1 addition & 1 deletion lib/plugin/htmlReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ module.exports = function (config) {
finalState: test.state,
duration: test.duration || 0,
})
output.debug(`HTML Reporter: Fallback retry detection for failed test ${test.title}, attempts: ${fallbackAttempts}`)
output.debug(`HTML Reporter: Fallback retry detection for failed test ${test.title}, attempts: ${fallbackAttempts}`)
}
})

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
"repository": "Codeception/codeceptjs",
"scripts": {
"test-server": "node bin/test-server.js test/data/rest/db.json --host 0.0.0.0 -p 8010",
"mock-server:start": "node test/mock-server/start-mock-server.js",
"mock-server:stop": "kill -9 $(lsof -t -i:3001)",
"test:with-mock-server": "npm run mock-server:start && npm test",
"json-server:graphql": "node test/data/graphql/index.js",
"lint": "eslint bin/ examples/ lib/ test/ translations/ runok.js",
"lint-fix": "eslint bin/ examples/ lib/ test/ translations/ runok.js --fix",
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/config_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Scenario('change config 5 @WebDriverIO @Puppeteer @Playwright', ({ I }) => {

Scenario('make API call and check response @Playwright', ({ I }) => {
I.amOnPage('/')
I.makeApiRequest('get', 'https://reqres.in/api/users?page=2', { headers: {'x-api-key': 'reqres-free-v1'}})
I.makeApiRequest('get', 'http://localhost:3001/api/users?page=2', { headers: { 'x-api-key': 'reqres-free-v1' } })
I.seeResponseCodeIsSuccessful()
})

Expand Down
2 changes: 1 addition & 1 deletion test/data/app/view/form/fetch_call.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
const getPostData = () =>
getData("https://jsonplaceholder.typicode.com/posts/1");
const getCommentsData = () =>
getData("https://reqres.in/api/comments/1");
getData("http://localhost:3001/api/comments/1");
const getUsersData = () =>
getData("https://jsonplaceholder.typicode.com/users/1");
</script>
Expand Down
13 changes: 13 additions & 0 deletions test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ services:
env_file: .env
volumes:
- ./:/codecept/test
environment:
- MOCK_SERVER_HOST=mock_server
command: ['/codecept/node_modules/.bin/mocha', 'test/rest']
depends_on:
- json_server
- mock_server

test-acceptance.webdriverio:
build: ..
Expand Down Expand Up @@ -73,6 +76,16 @@ services:
- '8010:8010' # Expose to host
restart: always # Automatically restart the container if it fails or becomes unhealthy

mock_server:
<<: *test-service
entrypoint: []
command: npm run mock-server:start
ports:
- '3001:3001' # Expose to host
restart: always # Automatically restart the container if it fails or becomes unhealthy
environment:
- PORT=3001

puppeteer-image:
image: ghcr.io/puppeteer/puppeteer:22.4.1

Expand Down
12 changes: 6 additions & 6 deletions test/helper/Playwright_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ describe('Playwright', function () {
describe('#mockRoute, #stopMockingRoute', () => {
it('should mock a route', async () => {
await I.amOnPage('/form/fetch_call')
await I.mockRoute('https://reqres.in/api/comments/1', route => {
await I.mockRoute('http://localhost:3001/api/comments/1', route => {
route.fulfill({
status: 200,
headers: { 'Access-Control-Allow-Origin': '*' },
Expand All @@ -1032,7 +1032,7 @@ describe('Playwright', function () {
})
await I.click('GET COMMENTS')
await I.see('this was mocked')
await I.stopMockingRoute('https://reqres.in/api/comments/1')
await I.stopMockingRoute('http://localhost:3001/api/comments/1')
await I.click('GET COMMENTS')
await I.see('data')
await I.dontSee('this was mocked')
Expand All @@ -1041,9 +1041,9 @@ describe('Playwright', function () {

describe('#makeApiRequest', () => {
it('should make 3rd party API request', async () => {
const response = await I.makeApiRequest('get', 'https://reqres.in/api/users?page=2')
const response = await I.makeApiRequest('get', 'http://localhost:3001/api/users?page=2')
expect(response.status()).to.equal(200)
expect(await response.json()).to.include.keys(['page'])
expect(await response.json()).to.include.keys(['data'])
})

it('should make local API request', async () => {
Expand All @@ -1054,10 +1054,10 @@ describe('Playwright', function () {
it('should convert to axios response with onResponse hook', async () => {
let response
I.config.onResponse = resp => (response = resp)
await I.makeApiRequest('get', 'https://reqres.in/api/users?page=2')
await I.makeApiRequest('get', 'http://localhost:3001/api/users?page=2')
expect(response).to.be.ok
expect(response.status).to.equal(200)
expect(response.data).to.include.keys(['page', 'total'])
expect(response.data).to.include.keys(['data'])
})
})

Expand Down
4 changes: 2 additions & 2 deletions test/helper/Puppeteer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ describe('Puppeteer', function () {
describe('#mockRoute, #stopMockingRoute', () => {
it('should mock a route', async () => {
await I.amOnPage('/form/fetch_call')
await I.mockRoute('https://reqres.in/api/comments/1', request => {
await I.mockRoute('http://localhost:3001/api/comments/1', request => {
request.respond({
status: 200,
headers: { 'Access-Control-Allow-Origin': '*' },
Expand All @@ -1042,7 +1042,7 @@ describe('Puppeteer', function () {
})
await I.click('GET COMMENTS')
await I.see('this was mocked')
await I.stopMockingRoute('https://reqres.in/api/comments/1')
await I.stopMockingRoute('http://localhost:3001/api/comments/1')
await I.click('GET COMMENTS')
await I.see('data')
await I.dontSee('this was mocked')
Expand Down
1 change: 0 additions & 1 deletion test/helper/WebDriver.noSeleniumServer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@ describe('WebDriver - No Selenium server started', function () {
})
})


describe('#seeTitleEquals', () => {
it('should check that title is equal to provided one', async () => {
await wd.amOnPage('/')
Expand Down
68 changes: 68 additions & 0 deletions test/mock-server/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const express = require('express')
const app = express()
app.use(express.json())

// Example users data
let users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
]

// Example comments data
let comments = [{ id: 1, postId: 1, text: 'Great post!' }]

// GET /api/users
app.get('/api/users', (req, res) => {
res.json({ data: users })
})

// GET /api/comments/:id
app.get('/api/comments/:id', (req, res) => {
const comment = comments.find(c => c.id === parseInt(req.params.id))
if (comment) {
return res.json({
data: comment,
support: {
url: 'http://example.com/support',
text: 'Support information',
},
})
}
res.status(404).json({ error: 'Comment not found' })
})

// GET /api/users/:id
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id))
if (user) return res.json(user)
res.status(404).json({ error: 'User not found' })
})

// POST /api/users
app.post('/api/users', (req, res) => {
const { name, email } = req.body
const newUser = { id: users.length + 1, name, email }
users.push(newUser)
res.status(201).json(newUser)
})

// PUT /api/users/:id
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id))
if (!user) return res.status(404).json({ error: 'User not found' })
user.name = req.body.name || user.name
user.email = req.body.email || user.email
res.json(user)
})

// DELETE /api/users/:id
app.delete('/api/users/:id', (req, res) => {
users = users.filter(u => u.id !== parseInt(req.params.id))
res.status(204).send()
})

// Start server
const PORT = process.env.PORT || 3001
app.listen(PORT, () => {
console.log(`Mock REST server running on port ${PORT}`)
})
Loading