How do I use Perl's Remote::Selenium::WebElement to verify the URL a hyperlink will take me to? - perl

Seems like it should be straightforward but I can't seem to get to the bottom of it.
Here's the HTML I'm working with:
<li id="a" class="FILElevel3" onclick="changeMenu("b")">
<a onclick="stopBubble(event);" href="javascript:LinkPopup('/sub/URL.html')">Visible Text</a>
I'm able to find the element using XPaths:
my $returned_asset = $sel->find_element("//*[\#class='LINKlevel3']");
And I can verify this works because I'm able to extract the visible text from it:
my $returned_name = Selenium::Remote::WebElement::get_text($returned_asset);
I just can't seem to find the sequence to pull the HREF attribute from the element to put the link's URL into a verifiable string. Should I be able to do this using WebElement's get_attribute() method? I've tried variations on this:
my $returned_URL = $returned_asset-> Selenium::Remote::WebElement::get_attribute("a/href");
...where I've plugged in everything I could think of for that "a/href" string. What should go in there?
In the end I'd like to be able to put "javascript:LinkPopup('/sub/URL.html')" into a string and verify that my URL is in there.

have you tried
my $returned_asset = $sel->find_element("//*[\#class='LINKlevel3']/a");
my $returned_URL = $returned_asset->Selenium::Remote::WebElement::get_attribute("href");

Related

Typoscript filelink - Wrap URL within link

First, here is the Typoscript :
20 = TEXT
20 {
value {
field = field_title
wrap = |.txt
}
filelink {
stdWrap.wrap = <li>|</li>
path = fileadmin/txt-files/
}
}
The result I get is :
<li>
<a href="/fileadmin/txt-files/Title.txt">
<img src="typo3/sysext/frontend/Resources/Public/Icons/FileIcons/txt.png">
</a>
</li>
And what I need is :
<li>
<a href="/fileadmin/force_download_script.php?filepath=/fileadmin/txt-files/Title.txt">
<img src="typo3/sysext/frontend/Resources/Public/Icons/FileIcons/txt.png">
</a>
</li>
I need to make the link downloadable, rather than opening the file in the browser. For that I have a force_download_script.php, but when I do that :
wrap = fileadmin/force_download_script.php?filepath=|txt
instead of the current wrap, filelink doesn't find the file anymore.
I have tried using ATagBeforeWrap.wrap but it doesn't look like it's made for that purpose. I also tried typolinkConfiguration.wrap without any success.
Any idea of how to achieve that ? Using a COA maybe ?
Thank you !
I would not do this with a script, but with server configuration. If you use Apache and have .htaccess enabled, you can add the configuration to a .htaccess file in the directory where the files are located. See https://css-tricks.com/snippets/htaccess/force-files-to-download-not-open-in-browser/
Alternatively you can also use the HTML5 download attribute. This is not supported by Internet Explorer however (it is supported by Edge though).
The issue can get quite a bit complicated, but step by step:
your code above might be wrong if it's not just a copy & paste fault:
wrap = fileadmin/force_download_script.php?filepath=|.txt
The dot before txt was missing.
Nevertheless it is still interesting if the php-script is triggered.
It's possible that the script is not triggered due to some settings in typo3conf/LocalConfiguration.php respectively some settings in the install-tool.
Depending on the TYPO3-Version it's also possible that the script is not triggered at all because all scripts are being required now in an extension. That means you might need to create an extension for that script.
Also simple wrapping of the result with the script-path might not be enough, but you have to call it explicitly by TypoScript perhaps by including the script as user-function or lib.
The admin-panel might be useful to debug some things about your script but if not you've to include some debug-output first in your own code, if that's not enough in the core (temporary).
So you've to find out if your script is triggered and if not, the reason for it.
Are you sure .filelink is what you are looking for?
.filelink is for a set of files. For all files in the folder given by .path a link will be generated. see manual
From your description you want a text wrapped with a link to one single file. That would be more a problem for .typolink where you specify the link in .parameter.
if you really want a link list of multiple files, each wrapped with your script you need to modify .typolinkConfiguration.parameter which will be used internaly by .filelink.
Anyway it might be possible to do a wrap which then would be:
.typolinkConfiguration.parameter.wrap = /fileadmin/force_download_script.php?|
Maybe it is easier to build your list with .stdWrap.filelist, where you can use the filenames in any way to wrap your own href parameter for an A-tag.
To use the TYPO3 core solution with file links you can use this guide:
Create a file storage where you want your "secured" files in TYPO3 backend
Do not set the checkbox "Is public?" in the storage record
The links will be rendered with eID and file parameters
You can look into the FileDumpController handling these links: https://github.com/TYPO3/TYPO3.CMS/blob/2348992f8e3045610636666af096911436fa1c89/typo3/sysext/core/Classes/Controller/FileDumpController.php
You can use the included hook to extend this controller with your logic.
Unfortunately I can't find any official documentation for this feature, but will post it when I find something or wrote it myself. ;)
Maybe this can help you, too: https://extensions.typo3.org/extension/fal_securedownload/
Here is the official part, but it's not much: https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Fal/Administration/Storages.html?highlight=filedumpcontroller

Relative links in tvml?

Is it possible to use relative links in tvml? I've never had a problem using them in a webpage but just can't get it to work in my tvml docs.
From my swift:
static let TVBaseURL = "http://localhost:9001/"
This currently works from my tvml which is located at http://localhost:9001/templates/home.xml
<lockup onselect="getDocument('templates/Featured.xml')">
<img src="http://localhost:9001/graphics/icons/ICON_featured.png" width="313" height="600" />
</lockup>
Note that the onselect link is relative and works fine. However this doesn't work...
<lockup onselect="getDocument('templates/Featured.xml')">
<img src="../graphics/icons/ICON_featured.png" width="313" height="600" />
</lockup>
It all depends on how you define YOUR getDocument function. But from your code, most likely it looks a bit like this one from the official TVML Programming Guide, sec 8-3.
function getDocument(extension) {
var templateXHR = new XMLHttpRequest();
var url = baseURL + extension;
loadingTemplate();
templateXHR.responseType = "document";
templateXHR.addEventListener("load", function() {pushPage(templateXHR.responseXML);}, false);
templateXHR.open("GET", url, true);
templateXHR.send();
}
Which uses a pre-set baseURL like your code does. Thus, your get document support relative links. (and not universal link. putting the full http://localhost:9001/index.xml will break it.)
in this example, the XMLHttpRequest object open function, takes the full url, not the relative one. Read more about XMLHttpRequest open here.
In short. Nothing is relative here.
However, you can do something similar with the power of Javascript.
When you get a hold of the XML document, you can find all the tag with document.getElementsByTagName("img"), which give you a list of the image element. Then all it is left to do it to look at each of them with .item(i), get their source attribute by .getAttribute('src'), see if it start with http or https, and if not, set the new one by .setAttribute('src', baseUrl+imagePath)

How to pass a list of image filenames from Docpad to browser client

I want to get a list of filenames from a directory in my Docpad project and then pass them to the client for preloading. What is the best way to do this?
What I have been trying is to extract a list of file names from the directory and then pass them to the client via the document.
So I have a collection, like so in docpad.coffee:
collections:
myImages: ->
#getFilesAtPath({relativeOutDirPath: 'images'})
And then in the footer of my html, I've been trying something like this:
<script>
var images = <%= #getCollection('myImages').toJSON() %>
</script>
This however is not coming even close to working. What I really want to do is have images set to an array of urls pointing to the files. But I can't seem to figure out how this would be done. The Docpad documentation and the Query-Engine documentation are simply to sparse.
Anyone have any ideas? Or is there a totally different way to think about this? Is there a way to hand over a variable directly from the Node/Docpad backend to the client, by passing the need to pass it along with the HTML?
Not sure why you want to separate it as a script (btw if you want you can really put it in a separate script if it is called js.eco). I guess it is just for clear separation.
This is how it will work:
<script>
var images = [];
<%for obj in #getCollection("myImages").toJSON(): %>
images.push('<%= obj.url %>');
<% end %>
console.log(images[0]);
</script>
So you will have an array with url's only. I've put there an info to print out in console first element to show it works.

How can I get the anchor (#tag) from an <a> link in tritium?

I am trying to get the anchor tag from an anchor element link in the page eg
<a href="/page#reviews">
Is it possible to access the href so I can isolate #reviews and use it elsewhere in my Tritum script?
Thanks!
Yes, it's possible, using a two step process.
First, you can grab the value of the href attribute using the fetch() function.
Then, working on the isolated string, you can use regular expressions to replace all the characters that occur in front of the hash/pound sign (#) with a blank.
Here's an example using the Tritium Tester: http://tester.tritium.io/52503bcbe166ca7affa4944d90aae39808c8cd8e.
Note: This assumes that everything after the first # sign in the href attribute is what you're looking for.

Need to print out all links on a sidebar in selenium (xpath?)

I need to find any extra links and print them out. I started by doing:
get_xpath_count('//li/a')
and comparing it to the size of an array that holds the name of all the links for the sidebar. When the count is too high/low, I need to print out all the extra/missing links. I would like to make a list of the names so I can compare it to the array. I've tried a few things like get_text('//li/a'), which returns the name of the first. get_text('//li/a[1]) does the same, but any other index returns nothing.
Any ideas? Also, I need the name that's displayed on the link, not the actual href.
Edit* Also, i'm pretty new to selenium and Xpath. Please let me know if there's info I let out that is needed, or just any suggestions towards thew way I'm going about this.
I have been able to get this to work using CSS element locators. Since I use CSS selectors far more often than Xpath, I find it easier to always use them with Selenium as well.
$selenium->get_text("css=li a:nth-child(1)")
$selenium->get_text("css=li a:nth-child(2)")
$selenium->get_text("css=li a:nth-child(...)")
$selenium->get_text("css=li a:nth-child(n)")
Use:
(//li/a)[$someNumber]
this will get you the text of $someNumber-th //li/a in the XML document.
In order to know what values to use to substitute the $someNumber with, you need to know the total count of these elements:
count(//li/a)
This is in JAVA. You can use the same concept in perl
int totCountInPage=selenium.getXpathCount(//li/a);
for(int count=1;count<=totCountInPage;count++)
System.out.println(selenium.getText("xpath=//li[count]/a"));
This should print text inside the anchor links under all li tag.