testdriverai 7.2.28 → 7.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/sdk.js +59 -65
- package/test/testdriver/windows-installer.test.mjs +9 -17
package/package.json
CHANGED
package/sdk.js
CHANGED
|
@@ -1918,82 +1918,76 @@ with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
|
|
|
1918
1918
|
await this.dashcam.start();
|
|
1919
1919
|
}
|
|
1920
1920
|
|
|
1921
|
-
// Determine
|
|
1922
|
-
const urlObj = new URL(url);
|
|
1923
|
-
const detectedFilename = filename || urlObj.pathname.split('/').pop() || 'installer';
|
|
1924
|
-
|
|
1925
|
-
// Determine download directory and full path
|
|
1921
|
+
// Determine download directory
|
|
1926
1922
|
const downloadDir = this.os === 'windows'
|
|
1927
1923
|
? 'C:\\Users\\testdriver\\Downloads'
|
|
1928
1924
|
: '/tmp';
|
|
1929
|
-
const filePath = this.os === 'windows'
|
|
1930
|
-
? `${downloadDir}\\${detectedFilename}`
|
|
1931
|
-
: `${downloadDir}/${detectedFilename}`;
|
|
1932
1925
|
|
|
1933
1926
|
console.log(`[provision.installer] Downloading ${url}...`);
|
|
1934
1927
|
|
|
1935
|
-
|
|
1936
|
-
if (this.os === 'windows') {
|
|
1937
|
-
await this.exec(
|
|
1938
|
-
shell,
|
|
1939
|
-
`Invoke-WebRequest -Uri "${url}" -OutFile "${filePath}"`,
|
|
1940
|
-
300000, // 5 min timeout for download
|
|
1941
|
-
true
|
|
1942
|
-
);
|
|
1943
|
-
} else {
|
|
1944
|
-
await this.exec(
|
|
1945
|
-
shell,
|
|
1946
|
-
`curl -L -o "${filePath}" "${url}"`,
|
|
1947
|
-
300000,
|
|
1948
|
-
true
|
|
1949
|
-
);
|
|
1950
|
-
}
|
|
1928
|
+
let actualFilePath;
|
|
1951
1929
|
|
|
1952
|
-
//
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
if (!hasValidExtension && this.os === 'windows') {
|
|
1957
|
-
// On Windows, scan the download directory for .msi or .exe files
|
|
1958
|
-
console.log(`[provision.installer] Downloaded file has no extension, scanning for .msi or .exe files...`);
|
|
1959
|
-
const scanResult = await this.exec(
|
|
1960
|
-
shell,
|
|
1961
|
-
`Get-ChildItem -Path "${downloadDir}" -File | Where-Object { $_.Extension -match '\\.(msi|exe)$' } | Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName`,
|
|
1962
|
-
30000,
|
|
1963
|
-
true
|
|
1964
|
-
);
|
|
1930
|
+
// Download the file and get the actual filename (handles redirects)
|
|
1931
|
+
if (this.os === 'windows') {
|
|
1932
|
+
// Simple approach: download first, then get the actual filename from the response
|
|
1933
|
+
const tempFile = `${downloadDir}\\installer_temp_${Date.now()}`;
|
|
1965
1934
|
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1935
|
+
const downloadScript = `
|
|
1936
|
+
$ProgressPreference = 'SilentlyContinue'
|
|
1937
|
+
$response = Invoke-WebRequest -Uri "${url}" -OutFile "${tempFile}" -PassThru -UseBasicParsing
|
|
1938
|
+
|
|
1939
|
+
# Try to get filename from Content-Disposition header
|
|
1940
|
+
$filename = $null
|
|
1941
|
+
if ($response.Headers['Content-Disposition']) {
|
|
1942
|
+
if ($response.Headers['Content-Disposition'] -match 'filename=\\"?([^\\"]+)\\"?') {
|
|
1943
|
+
$filename = $matches[1]
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
# If no filename from header, try to get from URL or use default
|
|
1948
|
+
if (-not $filename) {
|
|
1949
|
+
$uri = [System.Uri]"${url}"
|
|
1950
|
+
$filename = [System.IO.Path]::GetFileName($uri.LocalPath)
|
|
1951
|
+
if (-not $filename -or $filename -eq '') {
|
|
1952
|
+
$filename = "installer"
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
# Move temp file to final location with proper filename
|
|
1957
|
+
$finalPath = Join-Path "${downloadDir}" $filename
|
|
1958
|
+
Move-Item -Path "${tempFile}" -Destination $finalPath -Force
|
|
1959
|
+
Write-Output $finalPath
|
|
1960
|
+
`;
|
|
1961
|
+
|
|
1962
|
+
const result = await this.exec(shell, downloadScript, 300000, true);
|
|
1963
|
+
actualFilePath = result ? result.trim() : null;
|
|
1979
1964
|
|
|
1980
|
-
if (
|
|
1981
|
-
|
|
1982
|
-
console.log(`[provision.installer] Found installer: ${actualFilePath}`);
|
|
1965
|
+
if (!actualFilePath) {
|
|
1966
|
+
throw new Error('[provision.installer] Failed to download file');
|
|
1983
1967
|
}
|
|
1984
|
-
} else
|
|
1985
|
-
//
|
|
1986
|
-
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
);
|
|
1968
|
+
} else {
|
|
1969
|
+
// Use curl with options to get the final filename
|
|
1970
|
+
const tempMarker = `installer_${Date.now()}`;
|
|
1971
|
+
const downloadScript = `
|
|
1972
|
+
cd "${downloadDir}"
|
|
1973
|
+
curl -L -J -O -w "%{filename_effective}" "${url}" 2>/dev/null || echo "${tempMarker}"
|
|
1974
|
+
`;
|
|
1975
|
+
|
|
1976
|
+
const result = await this.exec(shell, downloadScript, 300000, true);
|
|
1977
|
+
const downloadedFile = result ? result.trim() : null;
|
|
1993
1978
|
|
|
1994
|
-
if (
|
|
1995
|
-
actualFilePath =
|
|
1996
|
-
|
|
1979
|
+
if (downloadedFile && downloadedFile !== tempMarker) {
|
|
1980
|
+
actualFilePath = `${downloadDir}/${downloadedFile}`;
|
|
1981
|
+
} else {
|
|
1982
|
+
// Fallback: use curl without -J and specify output file
|
|
1983
|
+
const fallbackFilename = filename || 'installer';
|
|
1984
|
+
actualFilePath = `${downloadDir}/${fallbackFilename}`;
|
|
1985
|
+
await this.exec(
|
|
1986
|
+
shell,
|
|
1987
|
+
`curl -L -o "${actualFilePath}" "${url}"`,
|
|
1988
|
+
300000,
|
|
1989
|
+
true
|
|
1990
|
+
);
|
|
1997
1991
|
}
|
|
1998
1992
|
}
|
|
1999
1993
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Run: TD_OS=windows npx vitest run examples/windows-installer.test.mjs
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { describe,
|
|
12
|
+
import { describe, it } from "vitest";
|
|
13
13
|
import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
14
14
|
|
|
15
15
|
const isLinux = (process.env.TD_OS || "linux") === "linux";
|
|
@@ -19,7 +19,7 @@ describe("Windows App Installation", () => {
|
|
|
19
19
|
it.skipIf(isLinux)("should download, install, and launch GitButler on Windows", async (context) => {
|
|
20
20
|
// Alternative approach using provision.installer helper
|
|
21
21
|
const testdriver = TestDriver(context, {
|
|
22
|
-
|
|
22
|
+
reconnect: true,
|
|
23
23
|
os: 'windows'
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -29,21 +29,13 @@ describe("Windows App Installation", () => {
|
|
|
29
29
|
launch: false, // Don't auto-launch, we'll install manually
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
120000
|
|
40
|
-
);
|
|
41
|
-
} else {
|
|
42
|
-
await testdriver.exec('pwsh',
|
|
43
|
-
`Start-Process "${installerPath}" -ArgumentList "/S" -Wait`,
|
|
44
|
-
120000
|
|
45
|
-
);
|
|
46
|
-
}
|
|
32
|
+
console.log('Installer downloaded to:', installerPath);
|
|
33
|
+
|
|
34
|
+
// Install the MSI silently (the file might not have an extension, so we try MSI first)
|
|
35
|
+
await testdriver.exec('pwsh',
|
|
36
|
+
`Start-Process msiexec.exe -ArgumentList "/i \`"${installerPath}\`" /qn /norestart" -Wait`,
|
|
37
|
+
120000
|
|
38
|
+
);
|
|
47
39
|
|
|
48
40
|
// Verify installation by checking if executable exists
|
|
49
41
|
const verifyScript = `
|