'use strict' const path = require('path') const fs = require('fs') const prefixes = require('../src/prefixes') const runner = require('../src/runner') const wines = require('../src/wines') async function main() { const created = prefixes.createPrefix('e2e-test') if (!created.ok && created.error !== 'alreadyExists') throw new Error('prefix create failed: ' + created.error) const game = { id: 'e2e-test', name: 'E2E Test', mode: 'leave', path: '.', exePath: 'C:\\windows\\system32\\cmd.exe', workdir: path.resolve('.'), wine: 'system', prefix: 'e2e-test', args: '/c echo PLGL-E2E-OK > C:\\plgl-e2e-out.txt', dllOverrides: [{ dll: 'dinput8', setting: 'native' }], env: { E2E_MARKER: '1' } } const { env } = runner.buildEnv({ game, wine: { id: 'system', type: 'system' }, systemWine: true }) if (!env.WINEPREFIX.includes('e2e-test')) throw new Error('WINEPREFIX mismatch: ' + env.WINEPREFIX) if (env.WINEDLLOVERRIDES !== 'dinput8=native') throw new Error('dll overrides mismatch: ' + env.WINEDLLOVERRIDES) if (env.E2E_MARKER !== '1') throw new Error('game env not applied') console.log('PASS: system wine env', { WINEPREFIX: env.WINEPREFIX, WINEDLLOVERRIDES: env.WINEDLLOVERRIDES }) const protonDir = path.join(require('../src/paths').DIRS.WINES, 'e2e-fake-proton') fs.mkdirSync(protonDir, { recursive: true }) fs.writeFileSync(path.join(protonDir, 'proton'), '#!/usr/bin/env python3\n') await wines.refreshWines() const proton = wines.getWines().find(w => w.id === 'e2e-fake-proton') if (!proton) throw new Error('proton build not detected') if (proton.type !== 'proton') throw new Error('wrong type: ' + proton.type) const penv = runner.buildEnv({ game, wine: proton, systemWine: false }).env if (penv.STEAM_COMPAT_DATA_PATH !== path.join(require('../src/paths').DIRS.DATA, 'compat', 'e2e-test')) { throw new Error('compat path mismatch: ' + penv.STEAM_COMPAT_DATA_PATH) } if (penv.WINEPREFIX !== path.join(penv.STEAM_COMPAT_DATA_PATH, 'pfx')) throw new Error('proton WINEPREFIX mismatch') if (fs.readlinkSync(penv.STEAM_COMPAT_DATA_PATH) !== prefixes.prefixPath('e2e-test')) { throw new Error('compatdata is not symlinked to the prefix') } if (!fs.existsSync(penv.STEAM_COMPAT_CLIENT_INSTALL_PATH)) throw new Error('fake steam missing') console.log('PASS: proton env', { STEAM_COMPAT_DATA_PATH: penv.STEAM_COMPAT_DATA_PATH, CLIENT_INSTALL_PATH: penv.STEAM_COMPAT_CLIENT_INSTALL_PATH }) console.log('launching real wine...') await runner.runGame({ game, wine: { id: 'system', type: 'system' }, systemWine: true }) for (let i = 0; i < 45; i++) { await new Promise(r => setTimeout(r, 2000)) const outFile = path.join(env.WINEPREFIX, 'drive_c', 'plgl-e2e-out.txt') if (fs.existsSync(outFile)) { console.log('OUTPUT FILE CONTENT:', fs.readFileSync(outFile, 'utf8').trim()) console.log('E2E PASS: wine executed the exe and wrote the file') prefixes.deletePrefix('e2e-test') fs.rmSync(protonDir, { recursive: true, force: true }) await wines.refreshWines() return } } console.log('E2E SOFT-FAIL: prefix init not finished in time (first wine run can be slow)') prefixes.deletePrefix('e2e-test') fs.rmSync(protonDir, { recursive: true, force: true }) await wines.refreshWines() } main().catch(e => { console.error(e) process.exit(1) })