How to check whether a link is clickable in Playwright? - playwright

Consider the following screenshot:
modal
Here, only buttons I accept and More options are clickable. The modal background prevents any clicks to the navigation links. Is it possible to use Playwright to select only links that are in current viewport and that would receive a click event should one occur within their bounding box?
Thanks

You can use a combination of playwright's actionability checks to narrow down links / buttons to only those that are clickable. Start with locators to select all tags (or buttons or something else depending what you're looking for). Iterate through the locators you get and run the checks you want on each
locators = page.locator(selector)
locator_count = await locators.count()
for index in range(0, locator_count):
locator = locators.nth(index)
if await locator.is_visible() and await locator.is_enabled():
# do your action
...
Edit:
Reading more and it looks like you can actually do those actionability checks using the trial option with click.
page.click(selector, trial=True)
Thats the look before you leap method. Playwright also does these checks before each click and other events, so if you're just looking to perform an action on a valid element, you can just try a click and handle the error if it's not actionable. Like so:
locators = page.locator(selector)
locator_count = await locators.count()
for index in range(0, locator_count):
locator = locators.nth(index)
try:
await locator.click()
except TimeoutError:
# handle error. likely just skip this locator
continue

Related

Is there any way to listen to mouse::enter signal for awful.menu

I've recently started to use and customize awesomewm, and I'm really happy with how all components work together and with the related documentation.
Though I'm sometimes really disturbed when using the menu (awful.menu) and it's nature to block some actions. So I've wanted to add listener to the mouse::enter and mouse::leave signal to allow the widget to hide itself once the mouse leaves the widget area.
Something like:
menu:connect_signal('mouse::enter', function()
naughty.notify({
preset = naughty.config.presets.critical,
title = "Entered",
text = "Entered"
})
end)
But those signals don't seem to be emitted by this widget. I've dug through the docs but don't seem to find any documentation about signals emitted by this widget. My question is then: Is there any other signal with same functionality, or is this not possible with awful.menu?
The menu is a complicated object. You can dig in its internal and access menu.wibox:connect_signal("mouse::enter", function() end), but this is only the top-level wibox. Submenus generate their own menu instance and they only create that dynamically.
Thus, there is no easy way to connect signals like this, sorry.

How do i set an eVar value in Adobe Analytics?

I couldn't find an answer to my question anywhere so i decided to post it here.
So, we have eVar33 set up within adobe analytics, when someone submits a form on our website how do i set eVar33 equal to the email address field?
$("form").submit(function(){
$("input#email").val(eVar33);
});
I'm assuming you have an appmeasurement library (aka s_code) on your page. In that case, Crayon Violet is right, something like this is what you want:
$("form").submit(function(){
s.eVar33 = $("input#email").val();
});
That will set the variable. To send it to Adobe, you need to fire either s.t() (for a page view) or, as is more likely the case for you, s.tl() (for things you want to track not associated with a page view- https://marketing.adobe.com/resources/help/en_US/sc/implement/function_tl.html and https://marketing.adobe.com/resources/help/en_US/sc/implement/link_variables.html.)
I suspect in the end, you'd do something like this:
$("form").submit(function(){
s.eVar33 = $("input#email").val();
s.linkTrackVars="eVar33"
s.tl(this,"o","form submitted")
});

How can getLoadTime plugin be implemented in Adobe DTM?

Where do I make the initial function call to s_getLoadTime(). My library is being managed by Adobe.
https://marketing.adobe.com/resources/help/en_US/sc/implement/getLoadTime.html
Step 1: Add the plugin and timer start code
First, you need a Page Load Rule that is set to trigger at "Top of Page". If you already have an existing rule that triggers every page load at top of page, you can use that. If you do not, then create a new one.
Then, in the Javascript / Third Party Tags section, click on "Add New Script". Set the Type to "Sequential Javascript" and check the Execute Globally option.
In the code box, paste the following code:
// this is for older browser support
var inHeadTS=(new Date()).getTime();
// plugin
function s_getLoadTime(){if(!window.s_loadT){var b=new Date().getTime(),o=window.performance?performance.timing:0,a=o?o.requestStart:window.inHeadTS||0;s_loadT=a?Math.round((b-a)/100):''}return s_loadT}
// call plugin first time
s_getLoadTime();
Click on Save Code and then Save Rule.
Step 2: Make the 2nd call to plugin and assign to Adobe Analytics variables
Next, you need a Page Load Rule that is set to trigger at "Bottom of Page". If you already have an existing rule that triggers every page load at bottom of page, you can use that. If you do not, then create a new one.
Then, go to Conditions > Rule Conditions > Criteria and from the dropdown select Data > Custom and click "Add Criteria". In the code box, add the following:
_satellite.setVar('loadTime',s_getLoadTime());
return true;
Then within Adobe Analytics section of the rule, you can set your prop and/or eVar to %loadTime%.
Note: Using a rule set to trigger at "Onload" will technically be more accurate. However, DTM does not currently offer ability to trigger Adobe Analytics Onload (options are only for top or bottom of page), so if you set the rule to "Onload" it will trigger after AA has made a request so your variables will not be populated and sent in that request. If you really want to keep the accuracy then you will need to explore other options, such as implementing AA as a 3rd party script so that you have more control over when it triggers.
Click on Save Rule and then Approve/Publish once you have tested.
The question should really be, "Why should the getLoadTime() plugIn be used, ever?". Yasho, I started with the same question that you had and blindly implemented the plugIn in Adobe DTM following the instructions at https://marketing.adobe.com/resources/help/en_US/sc/implement/getLoadTime.html
Only after starting to analyze the data did I look into the plugIn to see what it does.
Below is the beautified code of the plugIn:
function s_getLoadTime() {
if (!window.s_loadT) {
var b = new Date().getTime(),
o = window.performance ? performance.timing : 0,
a = o ? o.requestStart : window.inHeadTS || 0;
s_loadT = a ? Math.round((b - a) / 100) : ''
}
return s_loadT
}
So, basically the function records s_loadT once and only once. The first call (way at the top of the page) sets the value and any subsequent call to the function will return that same value since it has been persisted in window.s_loadT
Scratch your head a bit and ask the obvious question, "So what does this measure anyway?" Best case, it measures the difference between window.performace.timing.requestStart and the timeStamp when the function was first called. Worst case it measures the difference between a timestamp set in the head of the document by javascript (and that difference could very well be a negative number). Or even worse if 'a' resolves to 0, you'll just get 'b' which will be a huge number.
If you are following the directions and calling getLoadTime() up high in the document (DTM page top rule), you're really just be measuring how long it takes to fire a page top rule. If you put the first call into the top of your s_code.js, you're just measuring how long it takes to load (and execute) s_code.js

How to link a google apps script in a google site

I'm creating a google site for my company and I'm utilizing google apps scripts to do a little extra on the site. I would really like to link a script to a drop-down menu that I made. However, I can't figure out how to link the script. I know how to link a script just as a google gadget and as a stand alone link, but I would really like to have the script run when I click on an item from my drop-down menu.
For security reasons, Google don't let you put javascript in Google Sites.
They provide Apps Scripts instead, but as they work on an isolated world (on the server rather than the browser), its very tricky and has its ways.
Because its very different to standard page's javascript, you have to rethink your goal in terms of what Apps Scripts lets you do.
Google Apps Scripts lets you build an User Interface (using its yet experimental UI API) that can be visualized as a standalone script in a full page or inserted in a iframe in Sites. This means you won't have a dropdown menu overlaping your site: you need an static space to visualize your script's UI.
There is another more primitive way to "embed" your scripts commands in your site: use links. A link that fires a script, even with your own parameters, only to run de command, but without any UI. You can make a menu with options, each of them fires a script. But I'm not talking about dropdown menu.
About Google Apps Scripts User Interfaces
https://developers.google.com/apps-script/guide_user_interfaces
https://developers.google.com/apps-script/guide_gui_builder
https://developers.google.com/apps-script/service_ui
Not sure what you mean by "link the script", do you have code someplace else? By "link" it sounds like you mean to "Call" the code, with an event handler. I'll show you how to call a function with a ServerHandler triggered by either a GUI ListBox Change event or from a Button Click event.
In Google Apps Scrips (GAS) there are three methods to do GUI.
HTML Service - Much like plain HTML, you could insert HTML form and input tags.
UI Service - Much like java (as far as layout managers), see below.
GUI Builder - I suggest doing it manually first to better understand layout.
In Google Sites you can add most HTML directly without a script. The UI Service and GUI Builder will generate HTML form tags for you, and since there's rarely any reason to insert GUI elements unless you are executing some code you probably want to start with using these.
Here is a Drop-Down list examplewith some changes to show how a handler function can be called from multiple UI elements (which they call Widgets sometimes) and how to use the parameter:
function doGet(e) { // use doGet() & UiApp to make a canvas.
var app = UiApp.createApplication();
var doEvent = app.createServerHandler('doEvent').setId('doEvent');
var myList = app.createListBox().setId('myList').setName('myList');
myList.addItem('one'); // add items, I use single quote strings.
myList.addItem('two').addItem('three') // I know it looks weird.
// Scripts let you do this, by returning self for your convenience.
.addChangeHandler(
app.createServerHandler('doEvent')
);
app.add(myList); // Add element to GUI.
doEvent.addCallbackElement(myList); // Add to Event Handler.
app.add(app.createButton('Click Me').setId('myButton')
.addClickHandler(doEvent));
return app;
} // Simple DropDown by Jason K.
function doEvent(e) { // use split() if isMultipleSelect is true
var app = UiApp.getActiveApplication();
app.add(app.createLabel(
'List Value is ' + e.parameter.myList
+ ' from ' + e.parameter.source));
return app;
}
As far as troubleshooting, remember to add each element with app.add() and return app; at the end of doGet and each handler function.
Handlers execute a function like JavaScript onClick() or onChange() functions, most UI are not useful without handlers. ClientHandler are more efficient but ServerHandler do more, start with ServerHandlers and any simple functions can be converted to ClientHandlers for better performance. You can choose to space out your handlers or cram it all into one line-of-code, really a matter of personal preference however do assign it to a variable if you plan to use it for more than one GUI object. You may want to look up the different layout managers to make more fancy looking applications, or just use the GUI Builder. Also there use to be other create functions like app.createServerClickHandler() but I understand those were useless and are now deprecated so ignore any other references you find like that, however we do still use addChangeHandler() and addClickHandler() to the GUI elements themselves.
The setName() seems to be silly, it is only needed to set the parameter name (I hope they change that) so for now I suggest just setting it the same as the element id. I also made the Handler's variable name = its id = the event function name just to illustrate how they are all related.

jQuery: how to go into sort mode, get out of it, apply order, and cancel sort?

I want the user to be able to trigger sorting mode. It's because I find that with long lists, updating takes long. If updating the position happens every time an item is dropped, it'd be slow and expensive.
This means that when they trigger the sorting mode, let's say by clicking on Start sorting, that's when I apply the .sortable(...) to the list I want them to sort.
My problem lies in these:
How do I disable the automatic update after everytime an item is dropped?
If the user decides that they don't want to sort it after all, how do I cancel it?
Thanks!
If you have a button that you want to use to "Start Sorting" the sortable, I would recommend this approach, assuming you have a DIV with an ID of "MyList"...
On document load or Init, create the sortable and deactivate it...
$(init);
function init() {
$("#MyLIst").sortable();
$("#MyLIst").sortable("disable");
}
Then when the user clicks the "Start Sorting" button...
$("#MyLIst").sortable("enable");
At this point I would prefer to change the "Start Sorting" button to "Finish Sorting", and when this button is clicked...
$("#MyLIst").sortable("disable");
I know this is an old question so I point out that this uses the latest JQuery as described here. I am not sure what the minimum version is that would allow for this to work.

Resources