Skip to content

Commit c8aabed

Browse files
committed
Merge branch 'release/2.11.0'
2 parents 253610e + f12c485 commit c8aabed

19 files changed

+446
-56
lines changed

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,42 @@ await page.GotoAsync("https://google.com");
178178

179179
The full example can be found [here](https://github.com/kameleo-io/local-api-examples/blob/master/dotnet-csharp/connect_with_playwright_to_firefox/Program.cs).
180180

181+
# Automate mobile profiles
182+
Kameleo can emulate mobile devices in the custom built Chromium.
183+
184+
```csharp
185+
var baseProfileList = await client.SearchBaseProfilesAsync(
186+
"mobile",
187+
"ios",
188+
"safari",
189+
"en-us");
190+
191+
// Create a new profile with recommended settings
192+
// Choose one of the Base Profiles
193+
// Set the launcher to 'chromium' so the mobile profile will be started in Chromium by Kameleo
194+
var createProfileRequest = BuilderForCreateProfile
195+
.ForBaseProfile(baseProfileList[0].Id)
196+
.SetRecommendedDefaults()
197+
.SetLauncher("chromium")
198+
.Build();
199+
200+
var profile = await client.CreateProfileAsync(createProfileRequest);
201+
202+
// Start the profile with a couple of extra parameters, so Selenium automation can be done fluently
203+
await client.StartProfileWithWebDriverSettingsAsync(profile.Id, new WebDriverSettings()
204+
{
205+
AdditionalOptions = new List<Preference>
206+
{
207+
// This allows you to click on elements using the cursor when emulating a touch screen in the brower.
208+
// If you leave this out, your script may time out after clicks and fail.
209+
new Preference("disableTouchEmulation", true),
210+
}
211+
});
212+
213+
// At this point you can automate the browser with your favorite framework
214+
```
215+
The full example can be found [here](https://github.com/kameleo-io/local-api-examples/blob/master/dotnet-csharp/automate_mobile_profiles_on_desktop/Program.cs).
216+
181217
# Example codes
182218
[Several examples](https://github.com/kameleo-io/local-api-examples) have been prepared in a different repository to showcase the most interesting features. Feel free to create a pull request to add new example codes.
183219

@@ -188,10 +224,14 @@ The full example can be found [here](https://github.com/kameleo-io/local-api-exa
188224
- Using Selenium with Local API
189225
- Using Playwright with Kameleo
190226
- Using Puppeteer with Kameleo
227+
- How to emulate mobile devices
191228
- Adding an HTTP, SOCKS or SSH proxy to profile
192229
- Saving/Loading a browsing session to/from a .kameleo file
193230
- Modify and Delete browser cookies
194231
- Start profile with extra WebDriver capabilities
232+
- How to duplicate virtual browser profiles
233+
- Test proxies
234+
- Refresh the browser of the emulated profiles
195235

196236
> Note: _If you are interested in more information about Kameleo, or have encountered an issue with using it, please check out our [Help Center](https://help.kameleo.io/)._
197237

docs/swagger.json

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@
729729
}
730730
},
731731
"/profiles/{guid}/duplicate": {
732-
"post": {
732+
"get": {
733733
"tags": [
734734
"Profile"
735735
],
@@ -803,7 +803,7 @@
803803
}
804804
},
805805
"/profiles/{guid}/upgrade": {
806-
"post": {
806+
"get": {
807807
"tags": [
808808
"Profile"
809809
],
@@ -865,7 +865,8 @@
865865
"os",
866866
"plugins",
867867
"resolution",
868-
"version"
868+
"version",
869+
"webglMeta"
869870
],
870871
"type": "object",
871872
"properties": {
@@ -918,6 +919,9 @@
918919
"internal-pdf-viewer",
919920
"internal-nacl-plugin"
920921
]
922+
},
923+
"webglMeta": {
924+
"$ref": "#/definitions/WebglMeta"
921925
}
922926
}
923927
},
@@ -1095,19 +1099,16 @@
10951099
"format": "int64",
10961100
"description": "This unix timestamp formatted attribute is used to set persistent cookies. It signifies how long the browser should use the persistent cookie and when the cookie should be deleted.\r\nIf this attribute is not specified, then the lifetime of the cookie is the same as that of browser session, i.e.it will be a non-persistent cookie.",
10971101
"type": "integer",
1098-
"readOnly": true,
10991102
"example": 1568986993
11001103
},
11011104
"session": {
11021105
"description": "Session cookies are deleted when the current session ends. The browser defines when the \"current session\" ends, and some browsers use session restoring when restarting, which can cause session cookies to last indefinitely long.",
11031106
"type": "boolean",
1104-
"readOnly": true,
11051107
"example": false
11061108
},
11071109
"storeId": {
11081110
"description": "The ID of the cookie store containing this cookie.",
11091111
"type": "string",
1110-
"readOnly": true,
11111112
"example": "0"
11121113
}
11131114
}
@@ -1133,6 +1134,7 @@
11331134
"properties": {
11341135
"domain": {
11351136
"description": "The domain attribute signifies the domain for which the cookie is valid and can be submitted with every request for this domain or its subdomains. If this attribute is not specified, then the hostname of the originating server is used as the default value.",
1137+
"minLength": 1,
11361138
"type": "string",
11371139
"example": ".google.com"
11381140
},
@@ -1143,6 +1145,7 @@
11431145
},
11441146
"path": {
11451147
"description": "The path attribute indicates a URL path that must exist in the requested URL in order to send the Cookie header. The %x2F (\"/\") character is considered a directory separator, and subdirectories match as well.",
1148+
"minLength": 1,
11461149
"type": "string",
11471150
"example": "/gmail/about"
11481151
},
@@ -1192,12 +1195,14 @@
11921195
"screen",
11931196
"timezone",
11941197
"webgl",
1198+
"webglMeta",
11951199
"webRtc"
11961200
],
11971201
"type": "object",
11981202
"properties": {
11991203
"baseProfileId": {
12001204
"description": "The unique identifier of the base profile. This references the base profile which should be used to build the new profile.",
1205+
"minLength": 1,
12011206
"type": "string",
12021207
"example": "555b894595b5cd242ead1533218a5ee93dd7c7ebfbff4dccb80fdb112f6cda27"
12031208
},
@@ -1220,7 +1225,10 @@
12201225
"$ref": "#/definitions/CanvasSpoofingType"
12211226
},
12221227
"webgl": {
1223-
"$ref": "#/definitions/WebglSpoofingTypeWebglSpoofingOptionsMultiLevelChoice"
1228+
"$ref": "#/definitions/WebglSpoofingType"
1229+
},
1230+
"webglMeta": {
1231+
"$ref": "#/definitions/WebglMetaSpoofingTypeWebglMetaSpoofingOptionsMultiLevelChoice"
12241232
},
12251233
"audio": {
12261234
"$ref": "#/definitions/AudioSpoofingType"
@@ -1288,7 +1296,6 @@
12881296
"name": {
12891297
"description": "Name of the device. This is only available for mobile profiles.",
12901298
"type": "string",
1291-
"readOnly": true,
12921299
"example": "Samsung SM-A705FN"
12931300
}
12941301
}
@@ -1374,6 +1381,7 @@
13741381
"properties": {
13751382
"path": {
13761383
"description": "The path where the profile should be loaded from",
1384+
"minLength": 1,
13771385
"type": "string"
13781386
}
13791387
}
@@ -1461,8 +1469,7 @@
14611469
"properties": {
14621470
"code": {
14631471
"format": "int32",
1464-
"type": "integer",
1465-
"readOnly": true
1472+
"type": "integer"
14661473
},
14671474
"error": {
14681475
"type": "object",
@@ -1592,6 +1599,7 @@
15921599
"tags",
15931600
"timezone",
15941601
"webgl",
1602+
"webglMeta",
15951603
"webRtc"
15961604
],
15971605
"type": "object",
@@ -1635,7 +1643,10 @@
16351643
"$ref": "#/definitions/CanvasSpoofingType"
16361644
},
16371645
"webgl": {
1638-
"$ref": "#/definitions/WebglSpoofingTypeWebglSpoofingOptionsMultiLevelChoice"
1646+
"$ref": "#/definitions/WebglSpoofingType"
1647+
},
1648+
"webglMeta": {
1649+
"$ref": "#/definitions/WebglMetaSpoofingTypeWebglMetaSpoofingOptionsMultiLevelChoice"
16391650
},
16401651
"audio": {
16411652
"$ref": "#/definitions/AudioSpoofingType"
@@ -1724,6 +1735,7 @@
17241735
"properties": {
17251736
"path": {
17261737
"description": "The path where the profile should be saved.",
1738+
"minLength": 1,
17271739
"type": "string"
17281740
}
17291741
}
@@ -1877,6 +1889,7 @@
18771889
"startPage",
18781890
"timezone",
18791891
"webgl",
1892+
"webglMeta",
18801893
"webRtc"
18811894
],
18821895
"type": "object",
@@ -1885,7 +1898,10 @@
18851898
"$ref": "#/definitions/CanvasSpoofingType"
18861899
},
18871900
"webgl": {
1888-
"$ref": "#/definitions/WebglSpoofingTypeWebglSpoofingOptionsMultiLevelChoice"
1901+
"$ref": "#/definitions/WebglSpoofingType"
1902+
},
1903+
"webglMeta": {
1904+
"$ref": "#/definitions/WebglMetaSpoofingTypeWebglMetaSpoofingOptionsMultiLevelChoice"
18891905
},
18901906
"audio": {
18911907
"$ref": "#/definitions/AudioSpoofingType"
@@ -1934,6 +1950,7 @@
19341950
},
19351951
"name": {
19361952
"description": "Profile name property. The value obtained by file name for existing profiles. For new profiles the value is generated by a random name generator.",
1953+
"minLength": 1,
19371954
"type": "string"
19381955
},
19391956
"tags": {
@@ -2082,8 +2099,26 @@
20822099
}
20832100
}
20842101
},
2085-
"WebglSpoofingOptions": {
2086-
"description": "When the WebGL spoofing is set to noise these extra settings can be used to ovveride the values in the base profile.",
2102+
"WebglMeta": {
2103+
"required": [
2104+
"vendor"
2105+
],
2106+
"type": "object",
2107+
"properties": {
2108+
"vendor": {
2109+
"description": "The UnmaskedVendor field from WebGL context",
2110+
"type": "string",
2111+
"example": "Google Inc. (AMD)"
2112+
},
2113+
"renderer": {
2114+
"description": "The UnmaskedRenderer field from WebGL context",
2115+
"type": "string",
2116+
"example": "ANGLE (AMD, AMD Radeon(TM) RX Vega 11 Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
2117+
}
2118+
}
2119+
},
2120+
"WebglMetaSpoofingOptions": {
2121+
"description": "When the WebGL Meta spoofing is used, these settings can override the values in the base profile.",
20872122
"type": "object",
20882123
"properties": {
20892124
"vendor": {
@@ -2098,28 +2133,37 @@
20982133
}
20992134
}
21002135
},
2101-
"WebglSpoofingType": {
2102-
"description": "Tells the mode how the WebGL will be spoofed. Possible values:\r\n'noise': Add some noise to the WebGL generation\r\n'block': Completely block the 3D API\r\n'off': Turn off the spoofing, use the original settings",
2136+
"WebglMetaSpoofingType": {
2137+
"description": "Tells the mode how the WebGL vendor and renderer will be spoofed. Possible values:\r\n'automatic': The vendor and renderer values comes from the base profile.\r\n'manual': Manually set the vendor and renderer values.\r\n'off': Turn off the spoofing, use the original settings",
21032138
"enum": [
2104-
"noise",
2105-
"block",
2139+
"automatic",
2140+
"manual",
21062141
"off"
21072142
],
21082143
"type": "string"
21092144
},
2110-
"WebglSpoofingTypeWebglSpoofingOptionsMultiLevelChoice": {
2145+
"WebglMetaSpoofingTypeWebglMetaSpoofingOptionsMultiLevelChoice": {
21112146
"required": [
21122147
"value"
21132148
],
21142149
"type": "object",
21152150
"properties": {
21162151
"value": {
2117-
"$ref": "#/definitions/WebglSpoofingType"
2152+
"$ref": "#/definitions/WebglMetaSpoofingType"
21182153
},
21192154
"extra": {
2120-
"$ref": "#/definitions/WebglSpoofingOptions"
2155+
"$ref": "#/definitions/WebglMetaSpoofingOptions"
21212156
}
21222157
}
2158+
},
2159+
"WebglSpoofingType": {
2160+
"description": "Tells the mode how the WebGL will be spoofed. Possible values:\r\n'noise': Add some noise to the WebGL generation\r\n'block': Completely block the 3D API\r\n'off': Turn off the spoofing, use the original settings",
2161+
"enum": [
2162+
"noise",
2163+
"block",
2164+
"off"
2165+
],
2166+
"type": "string"
21232167
}
21242168
}
21252169
}

src/BuilderForCreateProfile.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,26 @@ public BuilderForCreateProfile SetCanvas(string value)
7676
/// <para>'off': Turn off the spoofing, use the original settings</para>
7777
/// </summary>
7878
/// <param name="value">Values can be: 'noise', 'block', 'off'</param>
79-
public BuilderForCreateProfile SetWebgl(string value, WebglSpoofingOptions options = null)
79+
public BuilderForCreateProfile SetWebgl(string value)
8080
{
81-
_profileRequest.Webgl.Value = value;
82-
_profileRequest.Webgl.Extra = options;
81+
_profileRequest.Webgl = value;
82+
83+
return this;
84+
}
85+
86+
/// <summary>
87+
/// <para>Tells the mode how the WebGL vendor and renderer will be spoofed. Possible values:</para>
88+
/// <para>'automatic': The vendor and renderer values comes from the base profile.</para>
89+
/// <para>'manual': Manually set the vendor and renderer values.</para>
90+
/// <para>'off': Turn off the spoofing, use the original settings.</para>
91+
/// </summary>
92+
/// <param name="value">Values can be: 'automatic', 'manual', 'off'</param>
93+
/// <param name="options">When the WebglMeta spoofing is set to manual the webgl gpu vendor and renderer is required. For example:
94+
/// Google Inc. (NVIDIA)/ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)</param>
95+
public BuilderForCreateProfile SetWebglMeta(string value, WebglMetaSpoofingOptions options = null)
96+
{
97+
_profileRequest.WebglMeta.Value = value;
98+
_profileRequest.WebglMeta.Extra = options;
8399

84100
return this;
85101
}
@@ -283,7 +299,8 @@ public BuilderForCreateProfile SetRecommendedDefaults()
283299
{
284300
_profileRequest.Name = "";
285301
_profileRequest.Canvas = "intelligent";
286-
_profileRequest.Webgl.Value = "off";
302+
_profileRequest.Webgl = "off";
303+
_profileRequest.WebglMeta.Value = "automatic";
287304
_profileRequest.Audio = "off";
288305
_profileRequest.Timezone.Value = "automatic";
289306
_profileRequest.Geolocation.Value = "automatic";
@@ -302,7 +319,8 @@ private static CreateProfileRequest Reset(string baseProfileId)
302319
{
303320
BaseProfileId = baseProfileId,
304321
Canvas = "off",
305-
Webgl = new WebglSpoofingTypeWebglSpoofingOptionsMultiLevelChoice("off"),
322+
Webgl = "off",
323+
WebglMeta = new WebglMetaSpoofingTypeWebglMetaSpoofingOptionsMultiLevelChoice("off"),
306324
Audio = "off",
307325
Timezone = new TimezoneSpoofingTypeTimezoneMultiLevelChoice("off"),
308326
Geolocation = new GeolocationSpoofingTypeGeolocationSpoofingOptionsMultiLevelChoice("off"),

src/Kameleo.LocalApiClient.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<Authors>Kameleo Team</Authors>
66
<Company>Kameleo</Company>
7-
<PackageTags>kameleo; stealth browsing platform; selenium; webdriver; browser automation; web scraping; puppeteer; headless; chrome; firefox; chromium; edge</PackageTags>
8-
<Version>2.10.0</Version>
7+
<PackageTags>kameleo; stealth browsing platform; anti-detect browser; selenium; webdriver; browser automation; web scraping; puppeteer; playwright; headless; chrome; firefox; chromium; edge</PackageTags>
8+
<Version>2.11.0</Version>
99
<Description>This .NET Standard package provides convenient access to the Local API REST interface of the Kameleo Client.</Description>
1010
<PackageProjectUrl>https://kameleo.io</PackageProjectUrl>
1111
<RepositoryUrl>https://github.com/kameleo-io/local-api-client-csharp</RepositoryUrl>

src/KameleoLocalApiClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,7 +2783,7 @@ private void Initialize()
27832783
// Create HTTP transport objects
27842784
var _httpRequest = new HttpRequestMessage();
27852785
HttpResponseMessage _httpResponse = null;
2786-
_httpRequest.Method = new HttpMethod("POST");
2786+
_httpRequest.Method = new HttpMethod("GET");
27872787
_httpRequest.RequestUri = new System.Uri(_url);
27882788
// Set Headers
27892789

@@ -3058,7 +3058,7 @@ private void Initialize()
30583058
// Create HTTP transport objects
30593059
var _httpRequest = new HttpRequestMessage();
30603060
HttpResponseMessage _httpResponse = null;
3061-
_httpRequest.Method = new HttpMethod("POST");
3061+
_httpRequest.Method = new HttpMethod("GET");
30623062
_httpRequest.RequestUri = new System.Uri(_url);
30633063
// Set Headers
30643064

0 commit comments

Comments
 (0)