I have a Selenium 2.0 test system that works fine with Firefox. The pages are organized like so:
<html>
<head>
<frameset> 35,* rows
<frame> 'Header' 35 rows H x full width
<frameset> 182,* cols
<frame> 'TOC' remaining rows H x 182 cols W
<frameset> *,0,0 rows
<frame> 'Main' remaining rows H x remaining cols W
<frame> 'HiddenFrame' 0 rows H x remaining cols W
<frame> 'UploadFrame' 0 rows H x remaining cols W
(Please don't chew me out for this... I didn't write it and I can't change it. I just have to test it.)
Anyway, my code (Perl Selenium::Remote::Driver 0.17 language binding, 2.38.0 server) basically loads the page and then does a $driver->switch_to_frame(); $driver->switch_to_frame('TOC');. It works fine in Firefox, but in Chrome, after successfully loading the page, it returns "Server returned status code 204 but no data" and it's not going to the TOC (navigation) frame so I can click on links. The console error message mentions "no such frame".
Does Chrome (or Selenium using Chrome) do something different with frames? Note that these are not iframes, but old-fashioned frames. I can change the test code to do something different based on the browser model, if necessary. Thanks!
Add: here is the top-level HTML:
<html>
<head>
<frameset rows="35,*" framespacing="0" frameborder="NO" border="0">
<frame scrolling="NO" src="title.php" noresize="" name="Header" marginwidth="0" marginheight="0" frameborder="no">
<frameset cols="182,*" framespacing="2" frameborder="no" border="0">
<frame scrolling="auto" src="toc.php" name="TOC" marginwidth="2" marginheight="8" frameborder="no">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html> ... navigation frame
<head>
<body> ... links to expand/collapse categories, and page links
</html>
</frame>
<frameset rows="*,0,0" framespacing="0" frameborder="no" border="0">
<frame src="Welcome.php" name="Main" marginwidth="2" marginheight="10" frameborder="no">
<!DOCTYPE html>
<html> ... main content
<head>
<body> ... forms, output, buttons, etc.
</html>
</frame>
<frame src="javascript:''" name="HiddenFrame" frameborder="no">
<frame src="javascript:''" name="UploadFrame" frameborder="no">
</frameset>
</frameset>
<noframes>
<body bgcolor="#fff9f1" link="#0000ff" vlink="#0000ff" alink="#0000ff">
<p> Your browser does not support frames. The Administrator supports Netscape and Internet Explorer version 4.0 or later. </p>
</body>
</noframes>
</frameset>
</html>
It's a proprietary system and scripting language (not really .php) that's not publicly accessible, so I hope that's enough to figure out what's going on. Many thanks if you can spot what Chrome doesn't like, that Firefox has no problem with. Using the suggested workaround ($ele = $driver->find_element("//frame[#name='TOC']"); $driver->switch_to_frame($ele);, I can get into the TOC frame, but I can't do the same thing for 'Main' frame.
There is no difference in the frame handling between Chrome and Firefox. I do know that sometimes you can run Firefox with "native actions" and , in theory, it might be different if you did that, but most likely it sounds like you aren't doing that. So, I may be wrong, but in both cases, I believe Selenium most likely just uses Javascript to locate the frames.
I think the only way you are going to solve this is by writing a simple test example that reproduces the issue you think you are seeing. You could share it on GitHub. Then, with that example as proof of the problem, I think people would be more willing to help.
Related
Does XForms have a mechanism for manipulating attributes of the resultant HTML?
I guess I mean emitting HTML dynamically and setting the attributes as part of that.
I know that using a xf:repeat - you can effectively emit HTML elements, but I can't work out if this would stretch to attributes?
I'm using XSLTForms as the implementation - so maybe this support hooks for Javascript to do this if there isn't a built-in way?
The reason to ask specifically - I would like to work with the audio element (and some other HTML5 elements).
Yes, it is named AVT for Attribute Value Template. As in XSLT, just wrap XPath expressions into curly braces like in <div class="proto{$myclass}">.
Thanks to the help from Alain Couthures - I was able to put together the following. Sharing in case others find it interesting.
<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Podcast Player</title>
<xf:model>
<xf:instance xmlns="">
<data>
<url/>
</data>
</xf:instance>
<xf:instance id="feed" src="https://podcasts.files.bbci.co.uk/b05qqhqp.rss"/>
</xf:model>
<style><![CDATA[
* { font-family: arial; background-color:black; color: white }
]]></style>
</head>
<body>
<h1><xf:output ref="instance('feed')/channel/title"/></h1>
<blockquote><xf:output ref="instance('feed')/channel/description"/></blockquote>
<xf:select1 ref="url" appearance="full">
<xf:itemset nodeset="instance('feed')/channel/item">
<xf:label ref="title"/>
<xf:value ref="enclosure/#url"/>
</xf:itemset>
</xf:select1>
<audio src="{url}" controls="true"/>
</body>
</html>
The relevant bit to this post is the "audio" tag and in particular the "{url}" attribute template.
Here's a screenshot:
For those that wish to try this example, you'll need XSLTForms : https://en.wikibooks.org/wiki/XSLTForms , other XForms implementations are available.
Note: save the file with the extension '.xhtml' and place behind a webserver of your choice.
For instance using test HTTP servers: php, python etc.
I was looking to get open/click tacking using AMP for Emails
but yet to find any conclusive document to get any idea that how I can get tracking using AMP for emails.
Below is the sample code give by AMP but there is no tracking link of something given.
<!--
## Introduction
This sample demonstrates how to display a feed of data, allowing the user to go through
a large number of items in an email without having to scroll.
The sample uses a combination of [`amp-list`](/documentation/components/amp-list),
to fetch the initial items from the server and [`amp-form`](/documentation/components/amp-form),
to "refresh" a single item, by making a new server request.
-->
<!-- -->
<!doctype html>
<html ⚡4email lang="en" data-css-strict>
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<style amp4email-boilerplate>body{visibility:hidden}</style>
<!--
## Styles
We use CSS to hide the initially fetched item after the form is first submitted.
We also define a layout that allows us to have fixed card sizes, to ensure form submissions don't result in content jumps.
-->
<style amp-custom>
.amp-form-submit-success .initial-content,
.amp-form-submitting .initial-content,
.amp-form-submit-error .initial-content {
display: none;
}
.card {
width: 160px;
height: 120px;
margin: 10px;
float: left;
position: relative;
}
.card .next-button {
position: absolute;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<!--
## Single item template
Define a template for a single item inside a card and give it an `id`. This template is used by `amp-form` for displaying new items.
In this case, we use a single `amp-img`.
-->
<template id="item-template" type="amp-mustache">
<amp-img src="{{items.imageUrl}}" layout="fixed" width="160" height="90"></amp-img>
</template>
<!--
## Initial list of items
We define a template for the initial items and their layout and give it an `id`, allowing us to use it subsequently in an amp-list. This template is used by `amp-list` for fetching the initial up-to-date contents from the server.
It contains in itself an `amp-form` for each item which references the template defined above referred by its `id`. By using a different template for the `amp-form`, we're able to "refresh" a part of the content, namely the image in this case.
Note: This template contains the same markup (in this case, a single `amp-img`) as used in the template above to render the initial items. This is wrapped inside `<div class="initial-content">` which becomes hidden the first time the user submits the form.
-->
<template id="list-template" type="amp-mustache">
<form class="card" method="post" action-xhr="https://amp.dev/documentation/examples/api/photo-stream?single&width=160&height=90">
<div class="initial-content">
<amp-img src="{{imageUrl}}" layout="fixed" width="160" height="90"></amp-img>
</div>
<div submit-success template="item-template"></div>
<input class="next-button" type="submit" value="Next">
</form>
</template>
<!--
We use `amp-list` to render the initial items from the server using the template defined above referred by its `id`.
The height matches the combined height of our cards and their margins. The initial server response defines the number of cards to be displayed (in this case four).
-->
<amp-list template="list-template" src="https://amp.dev/documentation/examples/api/photo-stream?width=160&height=90&items=4" layout="fixed" width="360" height="280">
</amp-list>
</body>
</html>
Can anyone give a idea to implement tracking on this?
Thanks
The documentation says "AMPHTML allows tracking email opens with pixel tracking techniques, same as regular HTML emails."
There is therefore no specific AMP way of doing it--it's just normal.
So, normally the ESP handles open tracking, and perhaps click tracking too, by rewriting the URLs. Alternatively, you can add for example UTM links if you use Google Analytics on the site the links are going to.
I am getting validation errors with the inputmode attribute on text areas and text fields. The validator tells me Attribute inputmode not allowed on element input at this point but the HTML5 spec indicates that it is allowed.
Is there actually something wrong with this code, or is the validator at fault?
Here is a bare bones case which will produce exactly this kind of validation error (twice), in one case on an email input, and on the other on a textarea.
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<form method="post" action="contactme.php">
<label class='pas block'>
Your E-Mail:<br/>
<input type='email' name='email' required inputmode='latin' placeholder='your e-mail here' />
</label>
<label class='pas block'>
Your Message:<br/>
<textarea name='message' required inputmode='latin' placeholder='and your message here!'></textarea>
</label>
</form>
</body>
</html>
Also, see the chart about which attributes apply to the different input types here:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#attr-input-type
The "inputmode" attribute applies only to "text" and "search".
UPDATE 2019-09-04: "inputmode" is now a global attribute (per WHATWG) and can be specified on any HTML element: https://html.spec.whatwg.org/multipage/dom.html#global-attributes
Another reference page for "inputmode":
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode
On another note, "inputmode" is not a W3C HTML5 attribute, but it is a W3C HTML 5.1 attribute (at least at the time I'm writing this). UPDATE 2019-09-04: "inputmode" has been removed from HTML 5.2 and HTML 5.3.
The HTML5 spec says
The following content attributes must not be specified and do not apply to the element: accept, alt, checked, dirname, formaction, formenctype, formmethod, formnovalidate, formtarget, height, inputmode, max, min, src, step, and width.
It's under bookkeeping details at https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type=email)
Five years after the question was asked, some may wonder why some of the properties listed by #dsas doesn't trigger such errors, like enctype
The answer is simple support, while enctype for instance gained a wide support
inputmethod is supported only as of IE11 and Edge 14, for more infos click here
Is it possible to dynamically switch the title of a page that is served by Lift without having to write an extra snippet for that particular case?
One option is of course <lift:mySnippet><title>Default Title</title></lift:mySnippet> but I thought there might be an option along the lines of <head_merge><title>New Title</title></head_merge> (which inserts a second title node).
I do not like the first approach since I do not want to stick all the title generation logic into a single snippet and ask what kind of page I am on etc.
Have you tried to use templates?
You can define template in templates-hidden/default.html like this:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
<head>
<title>
<lift:bind name="title" />
</title>
...
</head>
<body>
<lift:bind name="content" />
</body>
</html>
And use it in index.html for example:
<lift:surround with="default">
<lift:bind-at name="title">Home</lift:bind-at>
<lift:bind-at name="content">
my content
</lift:bind-at>
</lift:surround>
You can find more information about templates here:
http://www.assembla.com/spaces/liftweb/wiki?id=liftweb&wiki_id=Templates_and_Binding
One way is to use the Menu.title snippet.
In bootstrap/liftweb/Boot.scala you define the sitemap with page names:
class Boot {
def boot {
// ...
def sitemap = SiteMap(
Menu.i("Home") / "index",
Menu.i("About") / "about")
// ...
}
}
In templates-hidden/default.html you use the snippet:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
<head>
...
<title class="lift:Menu.title">AppName:</title>
...
Then page titles will be: "AppName: Home" and "AppName: About". This is nice if you use
<span class="lift:Menu.builder"></span>
to build the menu, because page titles will be the same used in the menu.
Another approach is to use head merge and define the title in the page's html. For this to work, you have to remove the <title> tag from templates-hidden/default.html and put an <head> or <head_merge> tag in your content block:
<!DOCTYPE html>
<html>
<body class="lift:content_id=main">
<div id="main" class="lift:surround?with=default;at=content">
<head_merge>
<title>TITLE OF THIS PAGE HERE</title>
</head_merge>
...
I am using AjaxControlToolkit version 4.1.40412.0, .NET 4.0, VS2010
Using the TabContainer control I want to add/remove tabs dynamically, but it looks like all of my dynamic changes are not persistent. Here is my scenario: I start with a tabcontainer with 1 tabpanel (hardcoded, i.e. added at design time), then dynamically I add more tabpanels and hide the original tabpanel (run time). As expected I see only the new tabpanels on the page, however any time I try to select a different tab the whole control reverts back to its design time state, i.e. only shows the original tabpanel, which was supposed to be gone and the new tabpanels are nowhere to be found. What am I missing? I guess as a workaround I can add 50 or so tabs at design time and then dynamically hide/display rather than remove/add, but this seems clunky, sloppy and unnecessary.
Here is my code if you want to duplicate the issue:
ASPX
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"/>
<asp:TabContainer ID="tcMain" runat="server" AutoPostBack="true" ScrollBars="auto" >
<asp:TabPanel ID="tbTab0" runat="server" HeaderText="Tab0"/>
</asp:TabContainer>
</div>
</form>
</body>
</html>
ASPX.VB
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
For i As Integer = 0 To 3
Dim ol As New Label
ol.Text = i.ToString
Dim oT As New AjaxControlToolkit.TabPanel
oT.Controls.Add(ol)
oT.HeaderText = i.ToString
tcMain.Tabs.Add(oT)
Next
For i As Integer = 1 To tcMain.Tabs.Count
If tcMain.Tabs(tcMain.Tabs.Count - i).HeaderText = "Tab0" Then tcMain.Tabs.RemoveAt(tcMain.Tabs.Count - i)
Next
End If
End Sub
End Class
Note: If you comment out "If Not Page.IsPostBack Then" , i.e. run the code under it on every page load, the tabcontainer works as expected - I can select any tab without problems. In my real project this cannot be the solution though - I will be adding/removing tabs based on user input, so unless I keep a log of all changes ever made to the control I cannot load those changes every time the page loads.
You need to run your code in the page init or pre init, because by the page load, the page is already built along with the view state.