Skip to content

Commit b0046df

Browse files
Update API definitions
- Add new properties. - Remove redundant type. - Add methods to get new log types. - Add new query parameter.
1 parent 945d626 commit b0046df

File tree

11 files changed

+291
-85
lines changed

11 files changed

+291
-85
lines changed

src/MartinCostello.BrowserStack.Automate/AppJsonSerializerContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace MartinCostello.BrowserStack.Automate;
2121
[JsonSerializable(typeof(ProjectDetailItem))]
2222
[JsonSerializable(typeof(RecycleAccessKeyResult))]
2323
[JsonSerializable(typeof(Session))]
24+
[JsonSerializable(typeof(SetBuildTagRequest))]
2425
[JsonSerializable(typeof(SetNameRequest))]
2526
[JsonSerializable(typeof(SetSessionStatusRequest))]
2627
internal sealed partial class AppJsonSerializerContext : JsonSerializerContext

src/MartinCostello.BrowserStack.Automate/AutomationSessionDetail.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ internal sealed class AutomationSessionDetail
1212
/// Gets or sets the session.
1313
/// </summary>
1414
[JsonPropertyName("automation_session")]
15-
public SessionDetail SessionDetail { get; set; } = default!;
15+
public Session SessionDetail { get; set; } = default!;
1616
}

src/MartinCostello.BrowserStack.Automate/Browser.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,10 @@ public class Browser : IBrowserInfo
3838
/// </summary>
3939
[JsonPropertyName("browser")]
4040
public string BrowserName { get; set; } = string.Empty;
41+
42+
/// <summary>
43+
/// Gets or sets if a mobile device is used or not.
44+
/// </summary>
45+
[JsonPropertyName("real_mobile")]
46+
public bool? RealMobile { get; set; }
4147
}

src/MartinCostello.BrowserStack.Automate/BrowserStackAutomateClient.cs

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,15 @@ public virtual async Task<ICollection<Browser>> GetBrowsersAsync(CancellationTok
302302
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the builds.
303303
/// </returns>
304304
public virtual Task<ICollection<Build>> GetBuildsAsync(CancellationToken cancellationToken)
305-
=> GetBuildsAsync(null, null, null, cancellationToken);
305+
=> GetBuildsAsync(null, null, null, null, cancellationToken);
306306

307307
/// <summary>
308308
/// Gets the builds as an asynchronous operation.
309309
/// </summary>
310310
/// <param name="limit">The optional number of builds to return. The default value is 10.</param>
311311
/// <param name="offset">The optional offset for builds to return. The default value is 0.</param>
312312
/// <param name="status">The optional status to filter builds to.</param>
313+
/// <param name="projectId">The optional project Id to filter builds to, if any.</param>
313314
/// <param name="cancellationToken">The optional cancellation token to use.</param>
314315
/// <returns>
315316
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the builds.
@@ -318,9 +319,10 @@ public virtual async Task<ICollection<Build>> GetBuildsAsync(
318319
int? limit = default,
319320
int? offset = default,
320321
string? status = default,
322+
int? projectId = default,
321323
CancellationToken cancellationToken = default)
322324
{
323-
string relativeUri = AppendQuery("builds.json", limit, offset, status);
325+
string relativeUri = AppendQuery("builds.json", limit, offset, status, projectId);
324326

325327
var builds = await GetJsonAsync(
326328
relativeUri,
@@ -350,6 +352,30 @@ public virtual async Task<ProjectDetailItem> GetProjectAsync(int projectId, Canc
350352
return item!;
351353
}
352354

355+
/// <summary>
356+
/// Gets the badge for the project with the specified Id as an asynchronous operation.
357+
/// </summary>
358+
/// <param name="projectId">The Id of the project to get the status badge for.</param>
359+
/// <param name="cancellationToken">The optional cancellation token to use.</param>
360+
/// <returns>
361+
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the
362+
/// key for the status badge for the project with the specified Id.
363+
/// </returns>
364+
public virtual async Task<string> GetProjectStatusBadgeAsync(int projectId, CancellationToken cancellationToken = default)
365+
{
366+
using var response = await _client.GetAsync(
367+
FormattableString.Invariant($"projects/{projectId}/badge_key"),
368+
cancellationToken).ConfigureAwait(false);
369+
370+
await EnsureSuccessAsync(response, cancellationToken).ConfigureAwait(false);
371+
372+
#if NET8_0_OR_GREATER
373+
return await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
374+
#else
375+
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
376+
#endif
377+
}
378+
353379
/// <summary>
354380
/// Gets the projects as an asynchronous operation.
355381
/// </summary>
@@ -371,7 +397,7 @@ public virtual async Task<ICollection<Project>> GetProjectsAsync(CancellationTok
371397
/// <exception cref="ArgumentException">
372398
/// <paramref name="sessionId"/> is <see langword="null"/> or white space.
373399
/// </exception>
374-
public virtual async Task<SessionDetail?> GetSessionAsync(string sessionId, CancellationToken cancellationToken = default)
400+
public virtual async Task<Session?> GetSessionAsync(string sessionId, CancellationToken cancellationToken = default)
375401
{
376402
if (string.IsNullOrWhiteSpace(sessionId))
377403
{
@@ -450,6 +476,38 @@ public virtual Task<string> GetSessionConsoleLogsAsync(string buildId, string se
450476
public virtual Task<string> GetSessionNetworkLogsAsync(string buildId, string sessionId, CancellationToken cancellationToken = default)
451477
=> GetLogsAsync(buildId, sessionId, "networklogs", cancellationToken);
452478

479+
/// <summary>
480+
/// Gets the session Selenium logs associated with the specified build and session Id as an asynchronous operation.
481+
/// </summary>
482+
/// <param name="buildId">The build Id to return the logs for.</param>
483+
/// <param name="sessionId">The session Id to return the logs for.</param>
484+
/// <param name="cancellationToken">The optional cancellation token to use.</param>
485+
/// <returns>
486+
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the logs for the build and session
487+
/// with the specified Ids as a string.
488+
/// </returns>
489+
/// <exception cref="ArgumentException">
490+
/// <paramref name="buildId"/> or <paramref name="sessionId"/> is <see langword="null"/> or white space.
491+
/// </exception>
492+
public virtual Task<string> GetSessionSeleniumLogsAsync(string buildId, string sessionId, CancellationToken cancellationToken = default)
493+
=> GetLogsAsync(buildId, sessionId, "seleniumlogs", cancellationToken);
494+
495+
/// <summary>
496+
/// Gets the session Selenium 4 telemetry logs associated with the specified build and session Id as an asynchronous operation.
497+
/// </summary>
498+
/// <param name="buildId">The build Id to return the logs for.</param>
499+
/// <param name="sessionId">The session Id to return the logs for.</param>
500+
/// <param name="cancellationToken">The optional cancellation token to use.</param>
501+
/// <returns>
502+
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to get the logs for the build and session
503+
/// with the specified Ids as a string.
504+
/// </returns>
505+
/// <exception cref="ArgumentException">
506+
/// <paramref name="buildId"/> or <paramref name="sessionId"/> is <see langword="null"/> or white space.
507+
/// </exception>
508+
public virtual Task<string> GetSessionTelemetryLogsAsync(string buildId, string sessionId, CancellationToken cancellationToken = default)
509+
=> GetLogsAsync(buildId, sessionId, "telemetrylogs", cancellationToken);
510+
453511
/// <summary>
454512
/// Gets the sessions associated with the specified build Id as an asynchronous operation.
455513
/// </summary>
@@ -540,30 +598,33 @@ public virtual async Task<ICollection<Session>> GetSessionsAsync(
540598
}
541599

542600
/// <summary>
543-
/// Sets the name of the build with the specified Id as an asynchronous operation.
601+
/// Sets a tag of the build with the specified Id as an asynchronous operation.
544602
/// </summary>
545-
/// <param name="buildId">The build Id to set the name of.</param>
546-
/// <param name="name">The new name.</param>
603+
/// <param name="buildId">The build Id to set the tag for.</param>
604+
/// <param name="tag">The new build tag to set.</param>
547605
/// <param name="cancellationToken">The optional cancellation token to use.</param>
548606
/// <returns>
549607
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to set the name for the specified build Id.
550608
/// </returns>
551609
/// <exception cref="ArgumentException">
552-
/// <paramref name="name"/> is <see langword="null"/> or white space.
610+
/// <paramref name="tag"/> is <see langword="null"/> or white space.
553611
/// </exception>
554-
public virtual Task<Build?> SetBuildNameAsync(
612+
public virtual Task<Build?> SetBuildTagAsync(
555613
int buildId,
556-
string name,
614+
string tag,
557615
CancellationToken cancellationToken = default)
558616
{
559-
if (string.IsNullOrWhiteSpace(name))
617+
if (string.IsNullOrWhiteSpace(tag))
560618
{
561-
throw new ArgumentException("No name specified.", nameof(name));
619+
throw new ArgumentException("No tag specified.", nameof(tag));
562620
}
563621

564-
return SetNameAsync(
622+
var request = new SetBuildTagRequest() { BuildTag = tag };
623+
624+
return PutJsonAsync(
565625
FormattableString.Invariant($"builds/{buildId}.json"),
566-
name,
626+
request,
627+
AppJsonSerializerContext.Default.SetBuildTagRequest,
567628
AppJsonSerializerContext.Default.Build,
568629
cancellationToken);
569630
}
@@ -698,10 +759,16 @@ protected virtual void Dispose(bool disposing)
698759
/// <param name="limit">The limit to use, if any.</param>
699760
/// <param name="offset">The offset to use, if any.</param>
700761
/// <param name="status">The status to filter to, if any.</param>
762+
/// <param name="projectId">The project Id to filter to, if any.</param>
701763
/// <returns>
702764
/// The query string to use, if any.
703765
/// </returns>
704-
private static string AppendQuery(string relativeUri, int? limit, int? offset, string? status)
766+
private static string AppendQuery(
767+
string relativeUri,
768+
int? limit,
769+
int? offset,
770+
string? status,
771+
int? projectId = null)
705772
{
706773
var parameters = new Dictionary<string, string?>(3);
707774

@@ -730,6 +797,16 @@ private static string AppendQuery(string relativeUri, int? limit, int? offset, s
730797
parameters["status"] = status;
731798
}
732799

800+
if (projectId.HasValue)
801+
{
802+
if (projectId < 1)
803+
{
804+
throw new ArgumentOutOfRangeException(nameof(projectId), projectId.Value, "The projectId value cannot be less than one.");
805+
}
806+
807+
parameters["projectId"] = projectId.Value.ToString(CultureInfo.InvariantCulture);
808+
}
809+
733810
if (parameters.Count > 0)
734811
{
735812
relativeUri = QueryHelpers.AddQueryString(relativeUri, parameters);

src/MartinCostello.BrowserStack.Automate/Build.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,16 @@ public class Build
3333
/// </summary>
3434
[JsonPropertyName("status")]
3535
public string Status { get; set; } = string.Empty;
36+
37+
/// <summary>
38+
/// Gets or sets the public URL of the build, if any.
39+
/// </summary>
40+
[JsonPropertyName("public_url")]
41+
public string? PublicUrl { get; set; }
42+
43+
/// <summary>
44+
/// Gets or sets the build tag of the build, if any.
45+
/// </summary>
46+
[JsonPropertyName("build_tag")]
47+
public string? BuildTag { get; set; }
3648
}

src/MartinCostello.BrowserStack.Automate/Project.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@ public class Project
4444
/// </summary>
4545
[JsonPropertyName("group_id")]
4646
public int GroupId { get; set; }
47+
48+
/// <summary>
49+
/// Gets or sets the sub-group Id.
50+
/// </summary>
51+
[JsonPropertyName("sub_group_id")]
52+
public int? SubGroupId { get; set; }
4753
}

0 commit comments

Comments
 (0)