Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ _Put an `x` in the boxes that apply_
- [ ] New feature (non-breaking change that adds functionality or value)
- [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected)
- [ ] **Test fix** (non-breaking change that improves test stability or correctness)
- [ ] Chore/Maintenance (updates to build scripts, dependencies, or GitHub Actions)

## Documentation
- [ ] Have you proposed a file change/ PR with Appium to update documentation?
Expand Down
1 change: 0 additions & 1 deletion .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,4 @@ version-resolver:
default: patch

prerelease: false
prerelease-identifier: 'rc'
contribution-template: '- $NAME contributed via $PULL_REQUEST'
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
----

[![Functional Tests](https://github.com/appium/dotnet-client/actions/workflows/functional-test.yml/badge.svg)](https://github.com/appium/dotnet-client/actions/workflows/functional-test.yml)
[![Functional Tests (Android)](https://github.com/appium/dotnet-client/actions/workflows/functional-android-test.yml/badge.svg)](https://github.com/appium/dotnet-client/actions/workflows/functional-android-test.yml)
[![Functional Tests (iOS)](https://github.com/appium/dotnet-client/actions/workflows/functional-ios-test.yml/badge.svg)](https://github.com/appium/dotnet-client/actions/workflows/functional-ios-test.yml)
[![Unit Tests](https://github.com/appium/dotnet-client/actions/workflows/unit-test.yml/badge.svg)](https://github.com/appium/dotnet-client/actions/workflows/unit-test.yml)

----
Expand Down
2 changes: 1 addition & 1 deletion src/Appium.Net/Appium.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Selenium.WebDriver" Version="4.44.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.46.0" />
<PackageReference Include="System.Drawing.Common" Version="10.0.9" />
</ItemGroup>
</Project>
28 changes: 22 additions & 6 deletions src/Appium.Net/Appium/Service/DirectConnect.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Licensed under the Apache License, Version 2.0 (the "License");
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//See the NOTICE file distributed with this work for additional
//information regarding copyright ownership.
Expand Down Expand Up @@ -42,21 +42,37 @@ public DirectConnect(Response response)
this.Path = GetDirectConnectValue((Dictionary<string, object>)response.Value, DIRECT_CONNECT_PATH);
}

/// <summary>
/// Gets a value indicating whether this instance has the required members for attempting URI construction.
/// </summary>
private bool IsValid =>
this.Protocol != null &&
this.Host != null &&
this.Port != null &&
this.Path != null &&
this.Protocol.Equals("https", StringComparison.OrdinalIgnoreCase) &&
int.TryParse(this.Port, out int port) && port >= 0 && port <= 65535;

/// <summary>
/// Returns a URL instance built with members in the DirectConnect instance.
/// </summary>
/// <returns>A Uri instance</returns>
public Uri GetUri() {
if (this.Protocol == null || this.Host == null || this.Port == null || this.Path == null) {
public Uri GetUri()
{
if (!this.IsValid)
{
return null;
}

if (this.Protocol != "https")
try
{
var builder = new UriBuilder(this.Protocol, this.Host, int.Parse(this.Port), this.Path);
return builder.Uri;
}
catch (UriFormatException)
{
return null;
}

return new Uri(this.Protocol + "://" + this.Host + ":" + this.Port + this.Path);
}

/// <summary>
Expand Down
18 changes: 9 additions & 9 deletions test/integration/ImageComparison/ComparisonResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ public void TearDown()
[Test]
public void SaveVisualizationAsFile_NullFileName_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => _comparisonResult.SaveVisualizationAsFile(null));
Assert.Throws<ArgumentNullException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(null)));
}

[Test]
public void SaveVisualizationAsFile_EmptyFileName_ThrowsArgumentException()
{
var ex = Assert.Throws<ArgumentException>(() => _comparisonResult.SaveVisualizationAsFile(""));
var ex = Assert.Throws<ArgumentException>((Action)(() => _comparisonResult.SaveVisualizationAsFile("")));
Assert.That(ex.Message, Does.Contain("The file name must not be an empty string."));
}

Expand All @@ -86,7 +86,7 @@ public void SaveVisualizationAsFile_InvalidCharacters_ThrowsArgumentException()
}

string invalidFileName = "test" + invalidChars[0] + ".png";
var ex = Assert.Throws<ArgumentException>(() => _comparisonResult.SaveVisualizationAsFile(invalidFileName));
var ex = Assert.Throws<ArgumentException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(invalidFileName)));
Assert.That(ex.Message, Does.Contain("The file name contains invalid characters"));
}

Expand All @@ -101,7 +101,7 @@ public void SaveVisualizationAsFile_ReservedDeviceName_ThrowsArgumentException()
var invalidNames = new[] { "CON.png", "CON .png", "NUL.", "PRN " };
foreach (var name in invalidNames)
{
var ex = Assert.Throws<ArgumentException>(() => _comparisonResult.SaveVisualizationAsFile(name));
var ex = Assert.Throws<ArgumentException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(name)));
Assert.That(ex.Message, Does.Contain("reserved device name"));
}
}
Expand Down Expand Up @@ -135,14 +135,14 @@ public void SaveVisualizationAsFile_ValidSubdirectoryFileName_SavesFile()
public void SaveVisualizationAsFile_PathTraversalParentDirectory_ThrowsIOException()
{
string fileName = "../traversal_image.png";
Assert.Throws<IOException>(() => _comparisonResult.SaveVisualizationAsFile(fileName));
Assert.Throws<IOException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(fileName)));
}

[Test]
public void SaveVisualizationAsFile_AbsolutePathOutsideAllowed_ThrowsIOException()
{
string absolutePath = Path.Combine(Path.GetTempPath(), "absolute_image.png");
Assert.Throws<IOException>(() => _comparisonResult.SaveVisualizationAsFile(absolutePath));
Assert.Throws<IOException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(absolutePath)));
}

[Test]
Expand Down Expand Up @@ -181,7 +181,7 @@ public void SaveVisualizationAsFile_SymlinkTraversal_ThrowsIOException()
// Attempt to write a file via the symlink
string fileName = Path.Combine("local_sub", "symlink_dir", "image.png");

var ex = Assert.Throws<IOException>(() => _comparisonResult.SaveVisualizationAsFile(fileName));
var ex = Assert.Throws<IOException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(fileName)));
Assert.That(ex.Message, Does.Contain("symbolic link or reparse point"));
#else
Assert.Ignore("Skipping symlink test: Symbolic links are not supported on this target framework.");
Expand Down Expand Up @@ -228,7 +228,7 @@ public void SaveVisualizationAsFile_BrokenFileSymlinkTraversal_ThrowsIOException
return;
}

var ex = Assert.Throws<IOException>(() => _comparisonResult.SaveVisualizationAsFile("broken_file_link.png"));
var ex = Assert.Throws<IOException>((Action)(() => _comparisonResult.SaveVisualizationAsFile("broken_file_link.png")));
Assert.That(ex.Message, Does.Contain("symbolic link or reparse point"));
#else
Assert.Ignore("Skipping symlink test: Symbolic links are not supported on this target framework.");
Expand All @@ -241,7 +241,7 @@ public void SaveVisualizationAsFile_AlternateDataStreamsOnWindows_ThrowsArgument
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
string invalidFileName = "file.png:stream";
var ex = Assert.Throws<ArgumentException>(() => _comparisonResult.SaveVisualizationAsFile(invalidFileName));
var ex = Assert.Throws<ArgumentException>((Action)(() => _comparisonResult.SaveVisualizationAsFile(invalidFileName)));
Assert.That(ex.Message, Does.Contain("alternate data streams"));
}
else
Expand Down
Loading