I want to get a value (content) from the CSS of a pseudo element (::before) while inside a test made using WDIO and Appium for an Android hybrid app because the designer has stored the current responsive-design state there. So my tests would know which layout (elements) to expect.
Multiple answers to related questions (1; 2; 3) indicated that using .getComputedStyle() might be the only solution. But this does not seem to work in my tests. The error is window is not defined for window.getComputedStyle(...) or document is not defined if I use document.defaultView.getComputedStyle(...). Also selectors themselves can't address pseudo-elements it seems.
Example of one of my many attempts:
document.defaultView.getComputedStyle($('body'),'::before').getPropertyValue('content')
Question: Do I need to somehow import window or document to my test? Is there some other way to get window or document from inside the test?
Ultimately: how can I get the content value of ::before of the <body> of a hybrid Android app?
Thanks to Jeremy Schneider (#YmerejRedienhcs) & Erwin Heitzman (#erwinheitzman) for help!
One solution is to use the execute function:
let contentMode = browser.execute(() => {
let style = document.defaultView.getComputedStyle(document.querySelector('body'),'::before');
return style.getPropertyValue('content')
});
Alternatively maybe something could also be done with getHTML.
I'm all new to Xamarin and I'm currently working on a sample or a "prove of concept" app using Xamarin.Forms.
I'm supposed to perform a print task from this app though I'm not at this point sure what to print yet (the screen, content of a label, a file etc.).
Either way, what is the easiest way to print from a Xamarin.Forms app?
(current target is primarily Android 4.4+).
I hope this isn't too complicated :)
EDIT:
Ok let me just update this post as the original text might be a bit ambitious/vague.
I have a Xamarin.Forms project (+ an Android part) and I have some HTML available in the XF part of the project that I need to get into a WebView and print it.
From what I understand, the thing with the WebView has to be done on the Android part of the project due to the fact that this is where the printing will be handled.
I was hoping this could be done from code since I don't really need to display the WebView, just print it's content.
The Android part of the project has only the MainActivity and no layouts or XAML files.
I don't know where to add the WebView or how to access it (other than DependecyService seems to be a buzz word here) so I'm kinda stuck here.
I'm thinking that this task should be rather trivial to someone with a little more Xamarin experience than me.
Every platform XF supports has it's own mechanism for printing. XF does not provide any abstractions for printing in a cross-platform manner. You will need to write printing logic for each layer and expose it to XF using DependencyService (or some other DI engine).
Here is a good example, of course, using dependency service:
https://codemilltech.com/xamarin-forms-e-z-print/
I so wanted to do this but it was too hard. Finally built it into Forms9Patch - a MIT licensed open source project.
Verifying that Printing is available
Before printing, you should verify that printing is available on your device. To do so, call:
if (Forms9Patch.PrintService.CanPrint)
{
// do the printing here
}
Print the contents of a Xamarin.Forms.WebView
using Forms9Patch;
...
var myWebView = new Xamarin.Forms.WebView
myWebView.Source = new HtmlWebViewSource
{
Html = "some HTML text here"
};
...
myWebView.Print("my_print_job_name");
Note that your WebView does not have to be attached to a Layout. This allows you to Print without having to display the WebView in your app’s UI.
Printing an HTML string
using Forms9Patch;
...
var myHtmlString = #"
<!DOCTYPE html>
<html>
<body>
<h1>Convert to PNG</h1>
<p>This html will be converted to a PNG, PDF, or print.</p>
</body>
</html>
";
...
myHtmlString.Print("my_print_job_name");
PLEASE NOTE: iOS sometimes places the page breaks in weird places. I have a StackOverflow Bounty on why this happens and how to fix it.
Using EmbeddedResource as a source for a Xamarin.Forms.WebView
This is sort of an experimental feature I’ve built that I’ve found it useful. As such the documentation is sparse. It allow you to put HTML content in a folder in your app’s EmbeddedResources folder and then use it as a source for a WebView. A much nicer solution than using platform specific approach provided by Xamarin. It also supports putting all of the HTML content into a zip file. Please take a look at the source code to see how it works.
You can handle the printing of lists/ invoices .. with the xfinium pdf component from xamarin componentstore. With that you create your _pdffile and then call the following method which starts the adobereader from where you can select a printer (in my case google cloudprint)
public void printPdfToCloud(string _pdffile)
{
try
{
var saveto = System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.ToString(), "YourApp/"+_pdffile);
string file_path = saveto;
if (System.IO.File.Exists(file_path))
{
Android.Net.Uri pdfFile = Android.Net.Uri.FromFile(new Java.IO.File(file_path));
Intent pdfIntent = new Intent(Intent.ActionView);
pdfIntent.SetPackage("com.adobe.reader");
pdfIntent.SetDataAndType(pdfFile, "application/pdf");
pdfIntent.SetFlags(ActivityFlags.NoHistory);
StartActivity(pdfIntent);
}else
{
// give a note that the file does not exist
}
}
catch (Exception E)
{
// Do some Error dialog
}
}
I'm trying to localize a SSRS reports. I have a DLL that uses a ResourceManager to access resource files that are embedded in the dll. My report has a reference to the dll. The dll is signed and strongly named. The dll and resource files' dll are compiled and in MicrosoftVisualStudio9.0/Common7/IDE/PrivateAssemblies and in Microsoft SQL Server\MSRS10.REPORTSERVER\Reporting Services\ReportServer\bin. The resource dll's are also installed in the GAC using gacutil.
Occasionally the SSRS correctly finds the resource key it needs and displays it. However, when changing the resource files to add more key's and values, I cannot get the SSRS to access the newly added files. I have repeated all of the above steps and even uninstalled and installed the resources in the GAC. Still I cannot get it to work.
Any idea what step I'm missing? Clearly the process works, I'm just not repeating something that I need to be.
For those interested in a slightly different approach, you may want to try using a localization assembly that doesn't use the standard resource management, but instead relies on simple file IO. This makes making changes to existing resx files or adding new ones less problematic. You can add or change the resx files and instantly be able to retrieve values for use in the reports. I followed this example, with only minor tweaks and have been very happy with the results:
http://www.codeproject.com/Articles/294636/Localizing-SQL-Server-Reporting-Services-Reports
One note though, the steps to follow when adding the new CodeGroup are lacking a bit in that if you place the new CodeGroup anywhere except after the unnamed UnionCodeGroup (it's the one with the Url="$CodeGen$/*") your attempts to access your custom assembly will fail.
After a lot of digging I was able to find confirmation of this on one of the msdn pages (see the "Placement of CodeGroup Elements for Extensions" section). Their wording was that "it is recommended", but from my testing I'd say it's required, at least when testing directly on the report server:
http://msdn.microsoft.com/en-us/library/ms152828.aspx
The xpath to use in wix for this location in the rssrvpolicy.config file is:
//PolicyLevel/CodeGroup/CodeGroup[\[]#class='FirstMatchCodeGroup'[\]]/CodeGroup[\[]#PermissionSetName='ReportLocalization'[\]]
Here's an example of how this can be done in WiX using the util:XmlConfig extension:
<DirectoryRef Id="TARGETDIR">
<Component Id="I18N_RSSRVPOLICY_CONFIG" Guid="some GUID">
<util:XmlConfig
Id="RS_i18n_PermissionSet_remove_if_already_exists"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="delete"
On="install"
ElementPath="//NamedPermissionSets"
VerifyPath="//NamedPermissionSets/PermissionSet[\[]#Name='ReportLocalization'[\]]"
Node="element"
Sequence="100">
</util:XmlConfig>
<util:XmlConfig
Id="RS_i18n_PermissionSet_add"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="create"
On="install"
ElementPath="//NamedPermissionSets"
VerifyPath="//NamedPermissionSets/PermissionSet[\[]#Name='ReportLocalization'[\]]"
Node="document"
Sequence="101">
<![CDATA[
<PermissionSet class="NamedPermissionSet" version="1" Unrestricted="true" Name="ReportLocalization" Description="A special permission set that allows Execution and Assertion" />
]]>
</util:XmlConfig>
<util:XmlConfig
Id="RS_i18n_CodeGroup_remove_if_already_exists"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="delete"
On="install"
ElementPath="//PolicyLevel/CodeGroup/CodeGroup[\[]#class='FirstMatchCodeGroup'[\]]"
VerifyPath="//PolicyLevel/CodeGroup/CodeGroup[\[]#class='FirstMatchCodeGroup'[\]]/CodeGroup[\[]#PermissionSetName='ReportLocalization'[\]]"
Node="element"
Sequence="102">
</util:XmlConfig>
<util:XmlConfig
Id="RS_i18n_CodeGroup_add"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="create"
On="install"
ElementPath="//PolicyLevel/CodeGroup/CodeGroup[\[]#class='FirstMatchCodeGroup'[\]]"
VerifyPath="//PolicyLevel/CodeGroup/CodeGroup[\[]#class='FirstMatchCodeGroup'[\]]/CodeGroup[\[]#PermissionSetName='ReportLocalization'[\]]"
Node="document"
Sequence="103">
<![CDATA[
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ReportLocalization" Name="Verint.SSRS.Localization" Description="This grants the Verint.SSRS.Localization.dll ReportLocalization Permissions">
<IMembershipCondition class="UrlMembershipCondition" version="1" Url="UPDATE_ME"/>
</CodeGroup>]]>
</util:XmlConfig>
<util:XmlConfig
Id="RS_i18n_CodeGroup_update"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="create"
On="install"
ElementPath="//IMembershipCondition[\[]#Url='UPDATE_ME'[\]]"
Name="Url"
Value="[SQLREPORTINGSERVICESPATH]ReportServer\bin\Verint.SSRS.Localization.dll"
Node="value"
Sequence="104">
</util:XmlConfig>
<util:XmlConfig
Id="RS_i18n_REDP_CodeGroup_update"
File="[SQLREPORTINGSERVICESPATH]ReportServer\rssrvpolicy.config"
Action="create"
On="install"
ElementPath="//CodeGroup[\[]#Name='Report_Expressions_Default_Permissions'[\]]"
Name="PermissionSetName"
Value="FullTrust"
Node="value"
Sequence="105">
</util:XmlConfig>
</Component>
</DirectoryRef>
I recommend backing up the original config files (with WiX or custom actions). This can make uninstall easier since you can just replace those originals, and also because you can test this over and over again till it's doing what you want. Good luck to you all!
Are your rebuilding and redeploying all the satellite assemblies with each of your updates (including in the GAC)?
If not, it sounds like the problem is due to assembly versioning. There is a SatelliteContractVersion attribute that you can apply to your main assembly to help with this problem. Although rebuilding/resigning/redeploying all satellite assemblies each time you deploy an update may be easier.
So I was reading this stackoverflow post about "autoversioning" in ASP.NET MVC for CSS/JS files and was wondering what the "best" strategy is to do this.
The solution provided inserts an assembly number - which means everytime you publish - it will change EVERY SINGLE file which is not ideal because if you make modifications to just 1 *.css or *.js then it will change each and every file.
1) How can it be done just for "single files" instead of using site wide assembly using modification date or something on IIS7 ?
2) Also if I have some sort of "static" asset like - http://static.domain.com/js/123.js - how can I use rewrite to send the latest file for a request if someone has integrated this static link onto their site ?
i.e. http://static.domain.com/js/123.js is the link and when a request comes for this - check and send latest file ?
ASP.NET 4.5+ comes with a built-in bundling & minification framework
which is designed to solve this problem.
If you absolutely need a simple roll-your-own solution you can use the answer below, but I would always say the correct way is to use a bundling & minification framework.
You can modify the AssemblyInfo.cs file like so:
Change
[assembly: AssemblyVersion("1.0.0.0")]
to
[assembly: AssemblyVersion("1.0.*")]
This means that every time the project is built, it will have a new assembly version which is higher than the previous one. Now you have your unique version number.
Create an UrlHelperExtension class that will help get this information when needed in the views:
public static class UrlHelperExtensions
{
public static string ContentVersioned(this UrlHelper self, string contentPath)
{
string versionedContentPath = contentPath + "?v=" + Assembly.GetAssembly(typeof(UrlHelperExtensions)).GetName().Version.ToString();
return self.Content(versionedContentPath);
}
}
You can now easily add a version number to your views in the following manner:
<link href="#Url.ContentVersioned("style.css")" rel="stylesheet" type="text/css" />
When viewing your page source you will now have something that looks like
<link href="style.css?v=1.0.4809.30029" rel="stylesheet" type="text/css" />
UPDATE: The previous version did not work on Azure, I have simplified and corrected below. (Note, for this to work in development mode with IIS Express, you will need to install URL Rewrite 2.0 from Microsoft http://www.iis.net/downloads/microsoft/url-rewrite - it uses the WebPi installer, make sure to close Visual Studio first)
If you would like to change the actual names of the files, rather than appending a querystring (which is ignored by some proxies / browsers for static files) You can follow the following steps: (I know this is an old post, but I ran across it while developing a solution:
How to do it: Auto-increment the assembly version every time the project is built, and use that number for a routed static file on the specific resources you would like to keep refreshed. (so something.js is included as something.v1234.js with 1234 automatically changing every time the project is built) - I also added some additional functionality to ensure that .min.js files are used in production and regular.js files are used when debugging (I am using WebGrease to automate the minify process) One nice thing about this solution is that it works in local / dev mode as well as production. (I am using Visual Studio 2015 / Net 4.6, but I believe this will work in earlier versions as well.
Step 1: Enable auto-increment on the assembly when built
In the AssemblyInfo.cs file (found under the "properties" section of your project change the following lines:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
to
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
Step 2: Set up url rewrite in web.config for files with embedded version slugs (see step 3)
In web.config (the main one for the project) add the following rules in the <system.webServer> section I put it directly after the </httpProtocol> end tag.
<rewrite>
<rules>
<rule name="static-autoversion">
<match url="^(.*)([.]v[0-9]+)([.](js|css))$" />
<action type="Rewrite" url="{R:1}{R:3}" />
</rule>
<rule name="static-autoversion-min">
<match url="^(.*)([.]v[0-9]+)([.]min[.](js|css))$" />
<action type="Rewrite" url="{R:1}{R:3}" />
</rule>
</rules>
</rewrite>
Step 3: Setup Application Variables to read your current assembly version and create version slugs in your js and css files.
in Global.asax.cs (found in the root of the project) add the following code to protected void Application_Start() (after the Register lines)
// setup application variables to write versions in razor (including .min extension when not debugging)
string addMin = ".min";
if (System.Diagnostics.Debugger.IsAttached) { addMin = ""; } // don't use minified files when executing locally
Application["JSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.','0') + addMin + ".js";
Application["CSSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.', '0') + addMin + ".css";
Step 4: Change src links in Razor views using the application variables we set up in Global.asax.cs
#HttpContext.Current.Application["CSSVer"]
#HttpContext.Current.Application["JSVer"]
For example, in my _Layout.cshtml, in my head section, I have the following block of code for stylesheets:
<!-- Load all stylesheets -->
<link rel='stylesheet' href='https://fontastic.s3.amazonaws.com/8NNKTYdfdJLQS3D4kHqhLT/icons.css' />
<link rel='stylesheet' href='/Content/css/main-small.#HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/medium.#HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/large.#HttpContext.Current.Application["CSSVer"]' />
#RenderSection("PageCSS", required: false)
A couple things to notice here: 1) there is no extension on the file. 2) there is no .min either. Both of these are handled by the code in Global.asax.cs
Likewise, (also in _Layout.cs) in my javascript section: I have the following code:
<script src="~/Scripts/all3bnd100.min.js" type="text/javascript"></script>
<script src="~/Scripts/ui.#HttpContext.Current.Application["JSVer"]" type="text/javascript"></script>
#RenderSection("scripts", required: false)
The first file is a bundle of all my 3rd party libraries I've created manually with WebGrease. If I add or change any of the files in the bundle (which is rare) then I manually rename the file to all3bnd101.min.js, all3bnd102.min.js, etc... This file does not match the rewrite handler, so will remain cached on the client browser until you manually re-bundle / change the name.
The second file is ui.js (which will be written as ui.v12345123.js or ui.v12345123.min.js depending on if you are running in debug mode or not) This will be handled / rewritten. (you can set a breakpoint in Application_OnBeginRequest of Global.asax.cs to watch it work)
Full discussion on this at: Simplified Auto-Versioning of Javascript / CSS in ASP.NET MVC 5 to stop caching issues (works in Azure and Locally) With or Without URL Rewrite (including a way to do it WITHOUT URL Rewrite)
1)
Use file modification time instead. Here's an example:
public static string GeneratePathWithTime(string cssFileName)
{
var serverFilePath = server.MapPath("~/static/" + cssFileName);
var version = File.GetLastWriteTime(serverFilePath).ToString("yyyyMMddhhmmss");
return string.Format("/static/{0}/{1}", version, cssFileName);
}
This will generate a path like "/static/201109231100/style.css" for "style.css" (assuming the your style.css is located in the static directory).
You'll then add a rewrite rule in IIS to rewrite "/static/201109231100/style.css" to "/static/style.css". The version number will only be changed when the css file has been modified and only applies to modified files.
2)
You can handle the request to 123.js via an HttpModule and send the latest content of it, but I don't think you can guarantee the request gets the latest version. It depends on how the browser handles its cache. You can set an earlier expiration time (for example, one minute ago) in your response header to tell the browsers to always re-download the file, but it's all up to the browser itself to decide whether to re-download the file or not. That's why we need to generate a different path for our modified files each time we updated our files in your question 1), the browser will always try to download the file if the URL has never been visited before.
I wrote a Url Helper which does the CacheBusting for me.
public static string CacheBustedContent(this UrlHelper helper, string contentPath)
{
var path = string.Empty;
if (helper.RequestContext.HttpContext.Cache["static-resource-" + contentPath] == null)
{
var fullpath = helper.RequestContext.HttpContext.Server.MapPath(contentPath);
var md5 = GetMD5HashFromFile(fullpath);
path = helper.Content(contentPath) + "?v=" + md5;
helper.RequestContext.HttpContext.Cache.Add("static-resource-" + contentPath, path, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(24, 0, 0), System.Web.Caching.CacheItemPriority.Default, null);
}
else
{
path = helper.RequestContext.HttpContext.Cache["static-resource-" + contentPath].ToString();
}
return path;
}
You could replace the GetMD5HashFromFile() with CRC or any other sort of call which generates a unique string based on the contents or last-modified-date of the file.
The downside is this'll get called whenever the cache is invalidated. And if you change the file on live somehow, but don't reset the application pool, you'll probably need to touch the web.config to get it to reload correctly.
You might want to have a look at Dean Hume's Blogpost MVC and the HTML5 Application Cache. In that post, he points out an elegant way of automatically handling versioning per request, using a class library of #ShirtlessKirk:
#Url.Content("~/Content/Site.css").AppendHash(Request)
This question is really old now, but if anyone stumbles upon it, here's to my knowledge the current state of the art:
In ASP.NET Core you can use TagHelpers and simply add the asp-append-version attribute to any <link> or <script> tag:
<script src="~/js/my.js" asp-append-version="true"></script>
For both ASP.NET Core and Framework there is a NuGet Package called WebOptimizer (https://github.com/ligershark/WebOptimizer). It allows for both bundling and minification, and will also append a content-based version string to your file.
If you want to do it yourself, there is the handy IFileVersionProvider interface, which you can get from your IServiceProvider in .NET Core:
// this example assumes, you at least have a HttpContext
var fileVersionProvider = httpContext.RequestServices.GetRequiredService<IFileVersionProvider>();
string path = httpContext.Content("/css/site.css");
string pathWithVersionString = fileVersionProvider.AddFileVersionToPath(httpContext.Request.PathBase, path);
For .NET Framework, you can get the FileVersionProvider source from here: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Razor/src/Infrastructure/DefaultFileVersionProvider.cs
You will have to do some work, like replacing the Cache with MemoryCache.Default or a ConcurrentDictionary or something, but the 'meat' is there.
I am not able to display images from the file system in the xhtmls using <h:graphicImage> tag. I am using Spring webflow 2.0 and Richfaces 3.3.3
Should I write a separate servlet to serve the images from the file system ?
I looked into <a4j:mediaOutput> tag . Can I use this ? since createContent requires us to specify a method that will be used for content creating. I am unsure if we can use the flow variables/beans to execute methods in the tag.
You can always fetch the images placing under Web Pages folder
<h:graphicImage url="#{facesContext.externalContext.requestContextPath}\your_img_path_under_Web_pages" id="img" />
If you use <a4j:mediaOutput> tag, then yes you should give method in createContent which will draw the image.
<a4j:mediaOutput element="img" createContent="#{serviceBean.method}" value="#{dataBean}" mimeType="image/jpg" />
public void userImage(OutputStream out, Object data) throws IOException {/*your method body*/}