Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit a1cff23

Browse files
committed
replace ava with japa
1 parent 5c1daf2 commit a1cff23

16 files changed

Lines changed: 2060 additions & 1904 deletions

package-lock.json

Lines changed: 1802 additions & 1633 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"prepare": "husky install",
1010
"precommit": "lint-staged",
1111
"dev": "tsx scripts/build.ts --dev",
12-
"test": "NODE_OPTIONS=\"--import=tsx --no-warnings\" ava",
12+
"test": "tsx scripts/test.ts",
1313
"lint": "biome check .",
1414
"types": "tsc",
1515
"build": "tsx scripts/build.ts",
@@ -43,10 +43,12 @@
4343
},
4444
"devDependencies": {
4545
"@biomejs/biome": "^1.5.2",
46+
"@japa/assert": "^2.0.0-2",
47+
"@japa/runner": "^3.0.0-9",
4648
"@tsconfig/node20": "^20.1.2",
4749
"@types/node": "^20.11.5",
50+
"@types/sinon-chrome": "^2.2.15",
4851
"autoprefixer": "^10.4.16",
49-
"ava": "^6.0.1",
5052
"chokidar": "^3.5.3",
5153
"chrome-webstore-upload-cli": "^2.0.1",
5254
"esbuild": "^0.19.11",
@@ -71,10 +73,5 @@
7173
},
7274
"lint-staged": {
7375
"*.{ts,tsx,js,json}": "biome check --apply --no-errors-on-unmatched"
74-
},
75-
"ava": {
76-
"require": [
77-
"./test/_setup.js"
78-
]
7976
}
8077
}

scripts/test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @ts-expect-error
2+
import { assert } from '@japa/assert'
3+
// @ts-expect-error
4+
import { configure, processCLIArgs, run } from '@japa/runner'
5+
import chrome from 'sinon-chrome'
6+
7+
processCLIArgs(process.argv.splice(2))
8+
configure({
9+
files: ['src/**/*.spec.js'],
10+
plugins: [
11+
assert(),
12+
async () => {
13+
// @ts-expect-error
14+
global.location = new URL('https://www.faceit.com')
15+
16+
// @ts-expect-error
17+
global.chrome = chrome
18+
19+
global.chrome.runtime.id = 'testid'
20+
},
21+
],
22+
})
23+
24+
run()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { test } from '@japa/runner'
2+
import { parseHTML } from 'linkedom'
3+
import sinon from 'sinon'
4+
import { hasFeatureAttribute } from '../helpers/dom-element'
5+
import clickModalMatchReady, { FEATURE_NAME } from './click-modal-match-ready'
6+
7+
const faceitEnvs = [
8+
{
9+
env: 'faceit',
10+
html: '<div class="FuseModalPortal"><div class="sc-bklklh NYiAz"><div class="sc-blFMiU fwcYfZ"><div class="sc-cdoIaK gaeZTF"><h5 size="5" class="sc-dIHSXr eCRPLL sc-fGdiLE lDkFc">Match ready</h5><div class="sc-cdoIaK gaeZTF"><div class="MatchCheckInModal__Holder-sc-yu96n5-0 daGuZS"><div class="MatchCheckInModal__Row-sc-yu96n5-1 dZVETa"><span class="sc-cbPlza bctuZo"><span class="sc-cbPlza fwYLNG">Confirm your match</span> <br> for the <span class="sc-cbPlza MatchCheckInModal__TextPrimary-sc-yu96n5-3 fwYLNG jOluuF">Repeek</span></span></div><div class="MatchCheckInModal__Row-sc-yu96n5-1 dZVETa"><span class="sc-cbPlza jxujzL">Expires in:</span></div><div class="CircleCountdown__CircleSpinner-sc-r4xxuy-0 gAAWfG"><div class="CircleCountdown__CircleValue-sc-r4xxuy-2 hpeccx"><span class="sc-cbPlza CircleCountdown__StyledText-sc-r4xxuy-3 fwYLNG ixeNii">81</span></div><div class="CircleCountdown__CircleOuter-sc-r4xxuy-1 kAHaiS"></div></div></div></div></div><div class="sc-cbelJu UPaKd"><div class="sc-ifjxht ixStst"><button class="sc-bypJrT djmUHF sc-ddjGPC dzWORN">Accept</button></div></div></div></div></div>',
11+
},
12+
{
13+
env: 'faceit beta',
14+
html: '<div class="FuseModalPortal"><div class="styles__Backdrop-sc-664e1c0f-0 fngpeO"><div class="styles__ModalWrapper-sc-664e1c0f-5 dvvnKY"><div class="styles__ModalContent-sc-664e1c0f-6 bwnBtX"><h5 size="5" class="HeadingBase-sc-e48327c2-0 bNWKuw styles__ModalTitle-sc-664e1c0f-1 dvUFkO">Match ready</h5><div class="styles__ModalContent-sc-664e1c0f-6 bwnBtX"><div class="MatchCheckInModal__Holder-sc-dcfe9dbf-0 bmHfST"><div class="MatchCheckInModal__Row-sc-dcfe9dbf-1 kIAsaH"><span class="Text-sc-f75cefb7-0 gjVnMO"><span class="Text-sc-f75cefb7-0 kcmOTI">Confirm your match</span> <br> for the <span class="Text-sc-f75cefb7-0 MatchCheckInModal__TextPrimary-sc-dcfe9dbf-3 kcmOTI czsWFE">Repeek</span></span></div><div class="MatchCheckInModal__Row-sc-dcfe9dbf-1 kIAsaH"><span class="Text-sc-f75cefb7-0 fRfakl">Expires in:</span></div><div class="CircleCountdown__CircleSpinner-sc-fdab6df8-0 epBeYb"><div class="CircleCountdown__CircleValue-sc-fdab6df8-2 indqqy"><span class="Text-sc-f75cefb7-0 CircleCountdown__StyledText-sc-fdab6df8-3 kcmOTI kTMQcx">81</span></div><div class="CircleCountdown__CircleOuter-sc-fdab6df8-1 gvtNmS"></div></div></div></div></div><div class="styles__ModalActions-sc-664e1c0f-3 jvlAUO"><div class="styles__ModalMainActions-sc-664e1c0f-4 cnaJxg"><button class="ButtonBase__Wrapper-sc-9fae6077-0 bwdpsX Button__Base-sc-bcb6f5c8-0 gWLpuZ">Accept</button></div></div></div></div></div>',
15+
},
16+
]
17+
18+
test.group(FEATURE_NAME, () => {
19+
test('sets feature attribute - {env}')
20+
.with(faceitEnvs)
21+
.run(async ({ assert }, { html }) => {
22+
const { document } = parseHTML(html)
23+
24+
await clickModalMatchReady({ baseElement: document })
25+
26+
assert.isTrue(
27+
hasFeatureAttribute(
28+
FEATURE_NAME,
29+
document.querySelector('.FuseModalPortal'),
30+
),
31+
)
32+
})
33+
34+
test('clicks accept button - {env}')
35+
.with(faceitEnvs)
36+
.run(async ({ assert }, { html }) => {
37+
const { document } = parseHTML(html)
38+
39+
const acceptButton = document.querySelector('button')
40+
41+
acceptButton.onclick = sinon.spy()
42+
43+
await clickModalMatchReady({ baseElement: document })
44+
45+
assert.isTrue(acceptButton.onclick.calledOnce)
46+
})
47+
})

src/content/features/click-modal-party-invite-accept.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const partyInviteModalContentRegExp = new RegExp(
3535
export default async ({ baseElement, isFaceitBeta = IS_FACEIT_BETA } = {}) => {
3636
const modalElements = select.all(
3737
isFaceitBeta
38-
? '.ReactModalPortal div[class*="modal-next__Container"]'
38+
? '.ReactModalPortal:has(div[class*="modal-next__Container"])'
3939
: '.ReactModalPortal',
4040
baseElement,
4141
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { test } from '@japa/runner'
2+
import { parseHTML } from 'linkedom'
3+
import sinon from 'sinon'
4+
import { hasFeatureAttribute } from '../helpers/dom-element'
5+
import clickModalPartyInviteAccept, {
6+
FEATURE_NAME,
7+
} from './click-modal-party-invite-accept'
8+
9+
const faceitEnvs = [
10+
{
11+
env: 'faceit',
12+
html: '<div class="ReactModalPortal"><div class="ReactModal__Overlay ReactModal__Overlay--after-open" style="position: fixed; inset: 0px; background-color: rgba(0, 0, 0, 0.6); justify-content: center; align-items: flex-start; display: flex; overflow: auto; z-index: 1060;"><div class="ReactModal__Content ReactModal__Content--after-open" tabindex="-1" role="dialog" aria-modal="true" style="position: static; inset: inherit; border: none; background: none; overflow: visible; border-radius: inherit; outline: none; padding: 0px;"><div class="sc-jGONNV eeOWko"><div class="sc-dEMAZk eRZiMf"><h5 size="5" class="sc-dIHSXr eCRPLL sc-lopPiv dTBdcK">Invite to <span class="sc-imJffE hLozcV">party</span></h5><div class="sc-iugpza Txjh"><button class="sc-bypJrT djmUHF sc-ddjGPC gQPuSg"><i class="sc-iHbSHJ jkbxap"><svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg" color="white" height="16" width="16" class="sc-klVQfs gdbspr"><path d="M8 7.025L4.939 3.994 7.969.936 7.025 0l-3.03 3.06L.937.03 0 .967l3.062 3.035L.03 7.063.967 8l3.037-3.064 3.06 3.033z" fill="currentColor"></path></svg></i></button></div></div><div class="sc-gMFoeA echMrx"><div class="sc-DwsMf gDFJfT"><div class="sc-dXHaLi iAwINc sc-cwsewg fZDMEu" size="80"><img aria-label="avatar" async="" src="https://distribution.faceit-cdn.net/images/657b4f34-9aa7-40a2-a9e4-c6a55d2e37ee.jpeg" class="sc-fRLnnz jeta-dZ"></div><div class="sc-ebpHGS BJPam"><span class="sc-cbPlza fwYLNG">DACHEC_Bot invited you to join their party</span><span class="sc-cbPlza bctuZo">Click accept to join the party</span><span class="sc-cbPlza bctuZo">Time remaining: 11</span></div></div><div class="sc-jaZhys dcznqn"><div class="sc-eOPQkR kCAsay"><button class="sc-bypJrT djmUHF sc-ddjGPC iXRFJh">Decline</button><button class="sc-bypJrT djmUHF sc-ddjGPC dzWORN">Accept</button></div></div></div></div></div></div></div>',
13+
},
14+
{
15+
env: 'faceit beta',
16+
html: '<div class="ReactModalPortal"><div class="ReactModal__Overlay ReactModal__Overlay--after-open" style="position: fixed; inset: 0px; background-color: rgba(0, 0, 0, 0.6); justify-content: center; align-items: flex-start; display: flex; overflow: auto; z-index: 1060;"><div class="ReactModal__Content ReactModal__Content--after-open" tabindex="-1" role="dialog" aria-modal="true" style="position: static; inset: inherit; border: none; background: none; overflow: visible; border-radius: inherit; outline: none; padding: 0px;"><div class="modal-next__Container-sc-b6f0d17-0 ZrgS"><div class="Header__HeaderHolder-sc-2cc7dc89-0 buHuYI"><h5 size="5" class="HeadingBase-sc-e48327c2-0 bNWKuw Header__HeaderText-sc-2cc7dc89-1 jPWORZ">Invite to <span class="style__PrimaryText-sc-918d2fcb-4 djldSF">party</span></h5><div class="Header__CloseButtonContainer-sc-2cc7dc89-2 erCApM"><button class="ButtonBase__Wrapper-sc-9fae6077-0 bwdpsX Button__Base-sc-bcb6f5c8-0 gnShNk"><i class="Icon__Holder-sc-cac5ab18-0 CUA-DS"><svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg" color="white" height="16" width="16" class="Icon__StyledISvg-sc-cac5ab18-1 etGOee"><path d="M8 7.025L4.939 3.994 7.969.936 7.025 0l-3.03 3.06L.937.03 0 .967l3.062 3.035L.03 7.063.967 8l3.037-3.064 3.06 3.033z" fill="currentColor"></path></svg></i></button></div></div><div class="modal-next__Body-sc-b6f0d17-1 bOphMK"><div class="style__Holder-sc-918d2fcb-1 hEeDFz"><div class="Avatar__AvatarHolder-sc-89ce63d3-1 ejzlkk style__Avatar-sc-918d2fcb-0 hprtIr" size="80"><img aria-label="avatar" async="" src="https://distribution.faceit-cdn.net/images/657b4f34-9aa7-40a2-a9e4-c6a55d2e37ee.jpeg" class="Avatar__Image-sc-89ce63d3-2 hNxHpG"></div><div class="style__TextHolder-sc-918d2fcb-2 liNDFA"><span class="Text-sc-f75cefb7-0 kcmOTI">DACHEC_Bot invited you to join their party</span><span class="Text-sc-f75cefb7-0 gjVnMO">Click accept to join the party</span><span class="Text-sc-f75cefb7-0 gjVnMO">Time remaining: 7</span></div></div><div class="modal-next__Footer-sc-b6f0d17-2 fwatWi"><div class="style__ActionsHolder-sc-918d2fcb-3 laOydE"><button class="ButtonBase__Wrapper-sc-9fae6077-0 bwdpsX Button__Base-sc-bcb6f5c8-0 hgGeBh">Decline</button><button class="ButtonBase__Wrapper-sc-9fae6077-0 bwdpsX Button__Base-sc-bcb6f5c8-0 gWLpuZ">Accept</button></div></div></div></div></div></div></div>',
17+
},
18+
]
19+
20+
test.group(FEATURE_NAME, () => {
21+
test('sets feature attribute - {env}')
22+
.with(faceitEnvs)
23+
.run(async ({ assert }, faceitEnv) => {
24+
const { document } = parseHTML(faceitEnv.html)
25+
26+
await clickModalPartyInviteAccept({
27+
isFaceitBeta: faceitEnv.env === faceitEnvs[1].env,
28+
baseElement: document,
29+
})
30+
31+
assert.isTrue(
32+
hasFeatureAttribute(
33+
FEATURE_NAME,
34+
document.querySelector('.ReactModalPortal'),
35+
),
36+
)
37+
})
38+
39+
test('clicks accept button - {env}')
40+
.with(faceitEnvs)
41+
.run(async ({ assert }, faceitEnv) => {
42+
const { document } = parseHTML(faceitEnv.html)
43+
44+
const acceptButton = document.querySelectorAll('button')[2]
45+
46+
acceptButton.onclick = sinon.spy()
47+
48+
await clickModalPartyInviteAccept({
49+
isFaceitBeta: faceitEnv.env === faceitEnvs[1].env,
50+
baseElement: document,
51+
})
52+
53+
assert.isTrue(acceptButton.onclick.calledOnce)
54+
})
55+
})

src/content/helpers/elo.spec.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { test } from '@japa/runner'
2+
import { estimateRatingChange, predictRatingChange } from './elo'
3+
4+
test.group('elo', () => {
5+
test('estimateRatingChange', ({ assert }) => {
6+
assert.deepEqual(estimateRatingChange(2000, 2000), {
7+
gain: 25,
8+
loss: -25,
9+
})
10+
11+
assert.deepEqual(estimateRatingChange(5000, 1000), {
12+
gain: 1,
13+
loss: -50,
14+
})
15+
16+
assert.deepEqual(estimateRatingChange(1000, 5000), {
17+
gain: 50,
18+
loss: -1,
19+
})
20+
21+
assert.strictEqual(estimateRatingChange(1853, 1159).gain, 1)
22+
assert.strictEqual(estimateRatingChange(1836, 1726).gain, 17)
23+
assert.strictEqual(estimateRatingChange(1813, 1789).gain, 23)
24+
assert.strictEqual(estimateRatingChange(1750, 1669).loss, -31)
25+
assert.strictEqual(estimateRatingChange(1775, 1602).gain, 13)
26+
assert.strictEqual(estimateRatingChange(1754, 1703).gain, 21)
27+
assert.strictEqual(estimateRatingChange(1781, 1685).loss, -32)
28+
assert.strictEqual(estimateRatingChange(1811, 1746).loss, -30)
29+
assert.strictEqual(estimateRatingChange(1877, 1875).loss, -25)
30+
assert.strictEqual(estimateRatingChange(1871, 1870).gain, 25)
31+
assert.strictEqual(estimateRatingChange(1727, 1639).loss, -31)
32+
})
33+
34+
test('estimateRatingChange is off by +-1', ({ assert }) => {
35+
assert.strictEqual(estimateRatingChange(1789, 1865).gain, 31) // Actual: 30
36+
assert.strictEqual(estimateRatingChange(1907, 1816).loss, -32) // Actual: -31
37+
assert.strictEqual(estimateRatingChange(1787, 1783).gain, 24) // Actual: 25
38+
assert.strictEqual(estimateRatingChange(1781, 1721).gain, 20) // Actual: 21,
39+
assert.strictEqual(estimateRatingChange(2043, 1939).loss, -33) // Actual: -32
40+
assert.strictEqual(estimateRatingChange(2134, 2073).loss, -30) // Actual: -29
41+
}).fails()
42+
43+
test('predictRatingChange', ({ assert }) => {
44+
assert.deepEqual(predictRatingChange(0.5), {
45+
gain: 25,
46+
loss: -25,
47+
})
48+
49+
assert.deepEqual(predictRatingChange(0.52), {
50+
gain: 24,
51+
loss: -26,
52+
})
53+
assert.deepEqual(predictRatingChange(0.48), {
54+
gain: 26,
55+
loss: -24,
56+
})
57+
58+
assert.deepEqual(predictRatingChange(0.44), {
59+
gain: 28,
60+
loss: -22,
61+
})
62+
assert.deepEqual(predictRatingChange(0.56), {
63+
gain: 22,
64+
loss: -28,
65+
})
66+
67+
assert.deepEqual(predictRatingChange(0.55), {
68+
gain: 22,
69+
loss: -28,
70+
})
71+
assert.deepEqual(predictRatingChange(0.45), {
72+
gain: 28,
73+
loss: -22,
74+
})
75+
})
76+
})

src/content/helpers/pages.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { test } from '@japa/runner'
2+
import * as pages from './pages'
3+
4+
test.group('pages', () => {
5+
test('isRoomOverview', ({ assert }) => {
6+
const path = 'en/csgo/room/466ece1d-9f16-4b64-aa2d-826c60bc022f'
7+
8+
assert.isTrue(pages.isRoomOverview(path))
9+
assert.isFalse(pages.isRoomOverview(''))
10+
})
11+
})

src/content/helpers/stats.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test } from '@japa/runner'
2+
import { mapAverageStats, mapTotalStats } from './stats'
3+
4+
test.group('stats', () => {
5+
test('mapTotalStats', ({ assert }) => {
6+
const stats = {
7+
m1: 1,
8+
unnecessary: true,
9+
}
10+
11+
assert.deepEqual(mapTotalStats(stats), { matches: stats.m1 })
12+
})
13+
14+
test('mapAverageStats', ({ assert }) => {
15+
const createStat = (c2, c3, c4, i6, i2, teamId) => ({
16+
c2: c2.toString(),
17+
c3: c3.toString(),
18+
c4: c4.toString(),
19+
i6: i6.toString(),
20+
i2,
21+
teamId,
22+
unnecessary: true,
23+
})
24+
25+
const stats = [
26+
createStat(0.25, 0.27, 20, 6, '123', '123'),
27+
createStat(0.44, 0.32, 12, 8, '123', '345'),
28+
createStat(0.36, 0.41, 19, 9, '123', '123'),
29+
]
30+
31+
assert.deepEqual(mapAverageStats(stats), {
32+
averageKDRatio: 0.35,
33+
averageKRRatio: 0.33,
34+
averageHeadshots: 17,
35+
averageKills: 8,
36+
winRate: 67,
37+
})
38+
})
39+
})

src/shared/faceit-beta.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import browser from 'webextension-polyfill'
22

3-
const FACEIT_BETA_HOST = 'beta.faceit.com'
3+
export const FACEIT_BETA_HOST = 'beta.faceit.com'
44

55
const FACEIT_BETA_CONTENT_SCRIPT_ID = 'faceit-beta'
66

0 commit comments

Comments
 (0)