Jump to content

WebDriver UDF - Help & Support (II)


Danp2
 Share

Recommended Posts

@Danp2 I did what you suggested and added WD_Debug_Info 

You were right. I got this error message: "  Response: {"value":{"error":"element not interactable","message":"The command failed because the specified element is not pointer or keyboard interactable.","stacktrace":""}}  "

Is there a way around this? The element is in a hidden drop down menu that appears once you mouse over the main module.

Edited by nooneclose
Link to comment
Share on other sites

  • Moderators
4 hours ago, HJL said:

Hi Dan, here is my next problem. I want to click a button that contains either ButtonGreen.png or ButtonRed.png or ButtonBlue.png. The XPath didn't help because the numbers 0, 1, 2 change. So I have to find the button with the png.s and then click it. I tried with 
$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//*[@id="content-form:favorites:0:fav-image"]") and _WD_ElementAction($sSession,$sElement,"click") and similiar, but because the number between  :?:  (...favorites:0:....) is not always connected with the the name I did not succeed. So it must be a search with "src" and after that a click. Do you have an idea? I tried for hours and it didn't work. 

 

@HJL exactly what kind of form are your trying to manipulate. Almost sounds like a security measure of some sort.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

_WDStartup: OS:    WIN_10 WIN32_NT 18362 
_WDStartup: AutoIt:    3.3.14.5
_WDStartup: WD.au3:    0.2.0.9
_WDStartup: WinHTTP:    1.6.4.1

With a recenct update of Firefox a component I use to automatically log in to google stopped working,
I am trying to automate logging on to my google account with webdriver, however google prevents automated processes from doing this:

“This browser or app may not be secure”

Does anyone have a method to get around this?

My research tells me if you change the browser's user agent string you can avoid this, but I tried that and it didn't help.

Here is example code, you can use the dummy email address as the page will show the error after you enter your email address because you are using the Webdriver.

#include <WebDriver-0.2.0.7\wd_core.au3>

Global Const $user = "email@address.com"
Global Const $pass = "password123"

Global Const $Firefox_WD_EXE = "geckodriver.exe"
Global Const $Firefox_WD_DesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptSslCerts":true,"trustAllSSLCertificates":true,"applicationCacheEnabled":true,"databaseEnabled":true}}'

_WD_Option('Driver', $Firefox_WD_EXE)
_WD_Option('DriverParams', '--log trace')
_WD_Option('Port', 4444)

_WD_Startup()

$Firefox = _WD_CreateSession($Firefox_WD_DesiredCapabilities)
_WD_Navigate($Firefox, "https://accounts.google.com/signin/v2/identifier")

;click sign in
$sElement = _WD_FindElement($Firefox, $_WD_LOCATOR_ByXPath, "//input[@id='identifierId']")
If $sElement Then
    _WD_ElementAction($Firefox, $sElement, 'value', $user)
    $sElement = _WD_FindElement($Firefox, $_WD_LOCATOR_ByXPath, "//span[@class='RveJvd snByac']")
    _WD_ElementAction($Firefox, $sElement, 'click')
    Sleep(500)

    $sElement = _WD_FindElement($Firefox, $_WD_LOCATOR_ByXPath, "//input[@name='password']")
    _WD_ElementAction($Firefox, $sElement, 'value', $pass)
    $sElement = _WD_FindElement($Firefox, $_WD_LOCATOR_ByXPath, "//div[@id='passwordNext']")
    _WD_ElementAction($Firefox, $sElement, 'click')
    Sleep(500)
endif

 

 

 

Link to comment
Share on other sites

@boomingranny From https://support.google.com/accounts/answer/7675428?hl=en --

Quote

Sign in with a supported browser

To help protect your account, Google doesn’t let you sign in from some browsers. Google might stop sign-ins from browsers that:

  • Don’t support JavaScript or have Javascript turned off.
  • Have unsecure or unsupported extensions added.
  • Use automation testing frameworks.
  • Are embedded in a different application.

Also, do you have  2-Step Verification enabled.on your account?

Link to comment
Share on other sites

@Danp2 was this section of the demo suppose to move the mouse? Nothing moved for me. 

$sAction = '{"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"'
$sAction &= $sElement & '","' & $_WD_ELEMENT_ID & '":"' & $sElement & '"}},{"button":2,"type":"pointerDown"},{"button":2,"type":"pointerUp"}]}]}'

ConsoleWrite("$sAction = " & $sAction & @CRLF)

    _WD_Action($sSession, "actions", $sAction)
    sleep(5000)
    _WD_Action($sSession, "actions")
    sleep(5000)

 

Link to comment
Share on other sites

@Danp2 Last question for a long while hopefully.

I want to get the text "1 - 3 of 3" from the label. How would I go about doing that? When I tried 

$testLineNumsField = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//label[@id='mdcaa79e9-lb3']")
$testLineNums      = _WD_ElementAction($sSession, $testLineNumsField, 'property', 'text')
ConsoleWrite(@CRLF & @CRLF & "$testLineNums = " & $testLineNums & @CRLF & @CRLF)

I got nothing. 

Here is the HTML I can trying to get the text from.

<label class="text tht tCount  " id="mdcaa79e9-lb3" style="display:block;padding-left:2px;padding-top:2px;" ctype="label" align="left" targetid="mdcaa79e9-lb3" noclick="1">1 - 3 of 3</label> 

Never mind I figured it out. I needed to use 

$testLineNums = _WD_ElementAction($sSession, $testLineNumsField, 'text')

instead

Edited by nooneclose
problem solved
Link to comment
Share on other sites

21 hours ago, JLogan3o13 said:

@HJL exactly what kind of form are your trying to manipulate. Almost sounds like a security measure of some sort.

I have written a script that automatically registers our employees on different websites depending on the Windows-LoginName. This has the advantage that only I know the access data (stored in an encrypted Excel file) and additionally the employees do not have a list of more than 100 passwords on the desk. In addition, there is no problem when an employee leaves - he doesn't know any password except that for his personal login on his client.

I have no problems to find the credentials XPathes but after registering on that page (my example) I have to push just one of the buttons and I don't get it.

Edited by HJL
Link to comment
Share on other sites

  • Moderators

So are you the security admin for your organization? Just curious as it seems not a best practice way to go about things.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

3 hours ago, JLogan3o13 said:

So are you the security admin for your organization? Just curious as it seems not a best practice way to go about things.

I have presented the programming in a very simplified way, there are of course other security measures. In the end, it's like a self-written KeyPass that only works within the company with many advantages. Nobody can take the access data with him when leaving the company, no one outside the company can log in somewhere just for fun because they do not know any access data, the passwords can be almost arbitrary and absolutely random, since no one has to memorize them and have to type them tediously. There are some official automated accesses of this kind, some with token, but the passwords would be outside our own network as opposed to my solution. But what do you think is best practice? 

And back to my question: does anybody have an idea how to click the three buttons of my sample?

Link to comment
Share on other sites

@Danp2

Yes, it is google preventing automated logon, that is the challenge I am facing.
I do not use 2 factor authentication. I got around it by pausing the script at this stage, turning off marionette mode, then logging in manually,
Google is detecting marionette mode, it only happened in the last day or so and I'm amazed that they can do it when I am using Firefox!
The browser must reveal something that enables google to work out it is in marionette mode.

Even if i don't use my script and just use Marionette mode and try to manually log on I am blocked!
Anyway, I just manually log in for now... But I'll keep trying to find a work around and will post if I do. Cheers

Link to comment
Share on other sites

  • Moderators

@HJL and @Danp2 I am fine with it continuing with general webdriver questions so long as Danp2 is comfortable still helping.

I think answering questions around how to register so many passwords on a website, however, is not something we want to support. Even if you do not have malicious intent, HJL, it doesn't mean that someone else could not come along and use such code for less than upstanding purposes.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

6 hours ago, JLogan3o13 said:

@HJL and @Danp2 I am fine with it continuing with general webdriver questions so long as Danp2 is comfortable still helping.

I think answering questions around how to register so many passwords on a website, however, is not something we want to support. Even if you do not have malicious intent, HJL, it doesn't mean that someone else could not come along and use such code for less than upstanding purposes.

You are totally wrong. I don't try something like brute force or testing different passwords on websites to get admittance in any way. I just take our known credentials and open the corresponding sites just like any browser does with storaged passwords if set in this way. The difference is that in my case I have better control where the credentials are, not Google, Microsoft, keypass or someone else. There is no chance to misuse my script because you have to enter the credentials in advance. And for some sites even a token or a sms tan will be needed. And as I have written before, there are some more security things in the script. Even with the readable code nobody could do anything bad, it is only good for the known sites with the known credentials, for them it finds the place where to put the username and the password and the submit button.

In the above case I just wanted to save the user another click to save time after (!) he has been registered. Without correct credentials you don't come to that site.

I will try //img[contains(@src, 'ButtonGreen.png')] - thanks. My problem is, that I know AutoIt for some years, but only used it for small and easy programs as a beginner and I don't know anything about html.

Link to comment
Share on other sites

Let's say I have "www.google.com" in tab0 and I created a new tab with _WD_NewTab, tab1 with "www.amazon.com" that it's not the current visible tab.

So, tab0 "google" is the current one displayed and I want to change a var with ExecuteScript on tab1 "Amazon", without switching to tab1, like a hidden command.

Now, if I send a JS command with ExecuteScript I can only send to the current tab.

 

Edited by frank10
Link to comment
Share on other sites

Borrowing from code written by @seadoggie01, I am writing a code to read the current update status of Chrome browser. I can get to the proper level of shadow roots, but I am stuck with finding a div element within the shadow root. As I am just learning about shadow root, I would appreciate if if someone could guide me through this maze.

#include "wd_core.au3"
#include "wd_helper.au3"

_WD_Option('Driver', 'chromedriver.exe')
_WD_Option('Port', 9515)
_WD_Option('DriverParams', '--log-path=chrome.log')
Local $sDesiredCapabilities = '{"capabilities":{"alwaysMatch": {"goog:chromeOptions": {"w3c": true}}}}'

_WD_Startup()
Local $sSession = _WD_CreateSession($sDesiredCapabilities)

Sleep(50)
_WD_ConsoleVisible(False)

_WD_Navigate($sSession, "chrome://settings/help")
Local $oSettingsUISR = _WD_GetShadowRoot($sSession, $_WD_LOCATOR_ByTagName, "settings-ui")
Local $oTemp = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "#container", $oSettingsUISR)
Local $oSettingsMainSR = _WD_GetShadowRoot($sSession, $_WD_LOCATOR_ByCSSSelector, "#main", $oTemp)
Local $oSettingsAboutPageSR = _WD_GetShadowRoot($sSession, $_WD_LOCATOR_ByCSSSelector, "settings-about-page", $oSettingsMainSR)
Local $oSettingsChromeInfoSR = _WD_GetShadowRoot($sSession, $_WD_LOCATOR_ByCSSSelector, "settings-section", $oSettingsAboutPageSR)

Local $oChromeStatusDiv = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "#updateStatusMessage", $oSettingsChromeInfoSR)

_WD_HighlightElement($sSession, $oChromeStatusDiv, 1)

The SciTE console result:
 

>"C:\AutoIt3\SciTE\..\AutoIt3.exe" "C:\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\Users\CYCho\OneDrive\Chrome\WebDriver\Shadow-Root3.au3" /UserParams    
+>21:34:06 Starting AutoIt3Wrapper (19.1127.1402.0} from:SciTE.exe (4.2.0.0)  Keyboard:00000412  OS:WIN_10/  CPU:X64 OS:X64  Environment(Language:0412)  CodePage:949  utf8.auto.check:4
+>         SciTEDir => C:\AutoIt3\SciTE   UserDir => C:\Users\CYCho\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\CYCho\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.14.5)  from:C:\AutoIt3  input:C:\Users\CYCho\OneDrive\Chrome\WebDriver\Shadow-Root3.au3
+>21:34:07 AU3Check ended.rc:0
>Running:(3.3.14.5):C:\AutoIt3\autoit3.exe "C:\Users\CYCho\OneDrive\Chrome\WebDriver\Shadow-Root3.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart or Ctrl+BREAK to Stop.
_WD_IsLatestRelease: True
_WD_IsLatestRelease ==> Success
_WDStartup: OS: WIN_10 WIN32_NT 18363 
_WDStartup: AutoIt: 3.3.14.5
_WDStartup: WD.au3: 0.2.0.9 (Up to date)
_WDStartup: WinHTTP:    1.6.4.2
_WDStartup: Driver: chromedriver.exe
_WDStartup: Params: --log-path=chrome.log
_WDStartup: Port:   9515
__WD_Post: URL=HTTP://127.0.0.1:9515/session; $sData={"capabilities":{"alwaysMatch": {"goog:chromeOptions": {"w3c": true}}}}
__WD_Post: StatusCode=200; ResponseText={"value":{"capabilities":{"acceptInsecureCerts":false,"browserName":"chrome","browserVersion":"83.0....
_WD_CreateSession: {"value":{"capabilities":{"acceptInsecureCerts":false,"browserName":"chrome","browserVersion":"83.0.4103.61","chrome":{"chromedriverVersion":"83.0.4103.39 (ccbf011cb2d2b19b506d844400483861342c20cd-refs/branch-heads/4103@{#416})","userDataDir":"C:\\Users\\CYCho\\AppData\\Local\\Temp\\scoped_dir17520_1716583999"},"goog:chromeOptions":{"debuggerAddress":"localhost:57559"},"networkConnectionEnabled":false,"pageLoadStrategy":"normal","platformName":"windows","proxy":{},"setWindowRect":true,"strictFileInteractability":false,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss and notify","webauthn:virtualAuthenticators":true},"sessionId":"845d82e745b5db94f012e49b50d321e8"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/url; $sData={"url":"chrome://settings/help"}
__WD_Post: StatusCode=200; ResponseText={"value":null}...
_WD_Navigate: {"value":null}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element; $sData={"using":"tag name","value":"settings-ui"}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"7817ad1d-894c-4018-bc91-ea1bb3f2be79"}}...
_WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"7817ad1d-894c-4018-bc91-ea1bb3f2be79"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/execute/sync; $sData={"script":"return arguments[0].shadowRoot", "args":[{"element-6066-11e4-a52e-4f735466cecf":"7817ad1d-894c-4018-bc91-ea1bb3f2be79"}]}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"4bea44f0-881d-42c8-bb04-db8950fab60d"}}...
_WD_ExecuteScript: {"value":{"element-6066-11e4-a52e-4f735466cecf":"4bea44f0-881d-42c8-bb04-db8950fab60d"}}...
_WD_GetShadowRoot: 4bea44f0-881d-42c8-bb04-db8950fab60d
_WD_GetShadowRoot ==> Success
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element/4bea44f0-881d-42c8-bb04-db8950fab60d/element; $sData={"using":"css selector","value":"#container"}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"4bea08c8-a993-40ff-b071-ec7e2523a60d"}}...
_WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"4bea08c8-a993-40ff-b071-ec7e2523a60d"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element/4bea08c8-a993-40ff-b071-ec7e2523a60d/element; $sData={"using":"css selector","value":"#main"}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"0d97d131-b90b-4ce5-977e-908d85d51a3e"}}...
_WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"0d97d131-b90b-4ce5-977e-908d85d51a3e"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/execute/sync; $sData={"script":"return arguments[0].shadowRoot", "args":[{"element-6066-11e4-a52e-4f735466cecf":"0d97d131-b90b-4ce5-977e-908d85d51a3e"}]}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"3a7f6978-73bf-42e5-aaf9-1c0baa4e03bd"}}...
_WD_ExecuteScript: {"value":{"element-6066-11e4-a52e-4f735466cecf":"3a7f6978-73bf-42e5-aaf9-1c0baa4e03bd"}}...
_WD_GetShadowRoot: 3a7f6978-73bf-42e5-aaf9-1c0baa4e03bd
_WD_GetShadowRoot ==> Success
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element/3a7f6978-73bf-42e5-aaf9-1c0baa4e03bd/element; $sData={"using":"css selector","value":"settings-about-page"}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"8a2492fe-8e4b-4dd9-b7b9-c81b732c6973"}}...
_WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"8a2492fe-8e4b-4dd9-b7b9-c81b732c6973"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/execute/sync; $sData={"script":"return arguments[0].shadowRoot", "args":[{"element-6066-11e4-a52e-4f735466cecf":"8a2492fe-8e4b-4dd9-b7b9-c81b732c6973"}]}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"c5191d8a-62b0-42fa-8653-b5a5323bcf76"}}...
_WD_ExecuteScript: {"value":{"element-6066-11e4-a52e-4f735466cecf":"c5191d8a-62b0-42fa-8653-b5a5323bcf76"}}...
_WD_GetShadowRoot: c5191d8a-62b0-42fa-8653-b5a5323bcf76
_WD_GetShadowRoot ==> Success
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element/c5191d8a-62b0-42fa-8653-b5a5323bcf76/element; $sData={"using":"css selector","value":"settings-section"}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"c526917c-c379-47a7-a208-6b897aede4c3"}}...
_WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"c526917c-c379-47a7-a208-6b897aede4c3"}}
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/execute/sync; $sData={"script":"return arguments[0].shadowRoot", "args":[{"element-6066-11e4-a52e-4f735466cecf":"c526917c-c379-47a7-a208-6b897aede4c3"}]}
__WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"af27ee7e-7699-4612-923e-ca7fa43b4922"}}...
_WD_ExecuteScript: {"value":{"element-6066-11e4-a52e-4f735466cecf":"af27ee7e-7699-4612-923e-ca7fa43b4922"}}...
_WD_GetShadowRoot: af27ee7e-7699-4612-923e-ca7fa43b4922
_WD_GetShadowRoot ==> Success
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/element/af27ee7e-7699-4612-923e-ca7fa43b4922/element; $sData={"using":"css selector","value":"#updateStatusMessage"}
__WD_Post: StatusCode=404; ResponseText={"value":{"error":"no such element","message":"no such element: Unable to locate element: {\"method\...
_WD_FindElement: {"value":{"error":"no such element","message":"no such element: Unable to locate element: {\"method\":\"css selector\",\"selector\":\"#updateStatusMessage\"}\n  (Session info: chrome=83.0.4103.61)","stacktrace":"Backtrace:\n\tOrdinal0 [0x00AE9563+2725219]\n\tOrdinal0 [0x009E8551+1672529]\n\tOrdinal0 [0x008D0359+525145]\n\tOrdinal0 [0x00869755+104277]\n\tOrdinal0 [0x00864271+82545]\n\tOrdinal0 [0x0087AAD0+174800]\n\tOrdinal0 [0x008641F6+82422]\n\tOrdinal0 [0x0087ACE1+175329]\n\tOrdinal0 [0x00883D7C+212348]\n\tOrdinal0 [0x0087A94B+174411]\n\tOrdinal0 [0x00862528+75048]\n\tOrdinal0 [0x008635A0+79264]\n\tOrdinal0 [0x00863539+79161]\n\tOrdinal0 [0x009FD607+1758727]\n\tGetHandleVerifier [0x00C06546+1050150]\n\tGetHandleVerifier [0x00C06291+1049457]\n\tGetHandleVerifier [0x00C110D7+1094071]\n\tGetHandleVerifier [0x00C06B46+1051686]\n\tOrdinal0 [0x009F5B06+1727238]\n\tOrdinal0 [0x009FEB7B+1764219]\n\tOrdinal0 [0x009FECE3+1764579]\n\tOrdinal0 [0x00A14C05+1854469]\n\tBaseThreadInitThunk [0x77256359+25]\n\tRtlGetAppContainerNamedObjectPath [0x77E77C24+228]\n\tRtlGetAppContainerNamedObjectPath [0x77E77BF4+180]\n"}}
_WD_FindElement ==> No match: HTTP status = 404
__WD_Post: URL=HTTP://127.0.0.1:9515/session/845d82e745b5db94f012e49b50d321e8/execute/sync; $sData={"script":"arguments[0].style='border: 2px dotted red'; return true;", "args":[{"element-6066-11e4-a52e-4f735466cecf":""}]}
__WD_Post: StatusCode=404; ResponseText={"value":{"error":"stale element reference","message":"stale element reference: element is not attac...
_WD_ExecuteScript: {"value":{"error":"stale element reference","message":"stale element reference: element is not attac...
_WD_ExecuteScript ==> No match: HTTP status = 404
+>21:34:14 AutoIt3.exe ended.rc:0
+>21:34:14 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 8.437

 

Link to comment
Share on other sites

  • Jos locked this topic
Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...