Karma html2js doesn't seem to have created any __html__ array - karma-runner

I am attempting to set up tests for a Polymer application using Karma. However an essential element of those tests is the basic html fixture.
However, when I get to the code that tries to read the __html__ array. this gives an undefined.
I have included all the key files in a gist
https://gist.github.com/akc42/121c619ef2476ce82086
Because polymer.js needs to be loaded as the first script in head, and because Karma includes all the files as script tags, I have a PolymerTests.js script which adds the Polymer element to the head. It also defines a load fixtures function which should read one of the files that have been placed in __html__ and adds it to a container div in the main body of the test page.
var container; //Used to hold fixture
PolymerTests.loadFixture = function(fixture,done) {
container = document.createElement("div");
container.innerHTML = __html__[fixture];
document.body.appendChild(container);
waits(0);
done();
};
This is called in a beforeEach routine for a specific test.
However when I get there, I get undefined.
EDITED
The question of course is has anyone any idea how to work out what I am doing wrong. I tried a debug session, but can't see window.__html__ defined anywhere.

In order for the pre-processor to actually put files into the __html__ array is is necessary to ensure the files are also included in the "files" section of the karma configuration file. If there are not included there, they won't be put into the array.

Probably you also use ng-html2js preprocessor. And they have ugly thing in index.js:
// TODO(vojta): remove this in 0.11
'preprocessor:html2js': ['factory', require('./html2js')]
After removing it, it will work.

Related

Can you get access to a pages front matter (or other data) in a eleventy (11ty) plugin

I'm creating (would like to create) an eleventy (11ty) plugin that can automatically generate Open Graph images based on a pages data. So in the template:
---
generate_og_image: true
image_text: "text which will be baked into the image"
og_image_filename: some_file_name.jpg
---
#some markdown
...
I can process each file in my .eleventy.js file via plugin using:
module.exports = function (eleventyConfig) {
eleventyConfig.addLinter("og-image-generator", function(content, inputPath, outputPath) {
title = HOW_TO_ACCESS_TEMPLATE_FRONT_MATTER
createImage(title)
});
}
But only have access to the content, inputPath and outputPath of the template.
How can I access the front matter data associated with the Template? Or is there a better way to go about this?
Answering my own question. As #moritzlost mentioned it is not possible directly. I found this workaround.
eleventyComputed allows you to dynamically assign values to keys. It also allows you to call a custom shortcode.
You can pass whatever properties you like from the template into the shortcode. In this case ogImageName the image name, ogImageTemplate a template or background image and text which is the text to be written on that background.
You can even pass in other keys from your front matter and process them as you go.
---
layout: _main.njk
title: "Some title here"
eleventyComputed:
ogImageName: "{% ogCreateImage { ogImageName: title | slug, ogImageTemplate: 'page-blank.png', text: title } %}"
---
Then in .eleventy.js or a plugin:
eleventyConfig.addShortcode("ogCreateImage", function(props) {
const imageName = props.ogImageName
const imageTemplate = props.ogImageTemplate
const imageText = props.text
console.log('-----------------ogCreateImage-----------------');
console.log(`filename: ${imageName}`);
console.log(`using template: ${imageTemplate}`);
console.log(`with the text : ${imageText}`);
// call the image creation code — return filename with extension
const imageNameWithExtension = createOGImage(imageName, imageTemplate, imageText)
return imageNameWithExtension
});
Returning the final filename which you can use in your template.
I've also come across this problem. I don't think what you're trying to do is possible at the moment. There are not many ways for a plugin to hook into the build step directly:
Transforms
Linters
Events
I think events would be the best solution. However, events also don't receive enough information to process a template in a structured way. I've opened an issue regarding this on Github. For your use-case, you'd need to get structured page data in this hook as well. Or eleventy would need to provide a build hook for each page. I suggest opening a new feature-request issue or adding a comment with your use-case to my issue above so those hooks can be implemented.
Other solutions
Another solution that requires a bit more setup for the users of your plugin would be to add your functionality as a filter instead of an automatic script that's applied to every template. This means that the users of your plugin would need to add their own template which passes the relevant data to your filter. Of course this also gives more fine-control to the user, which may be beneficial.
I use a similar approach for my site processwire.dev:
A special template loops over all posts and generates an HTML file which is used as a template for the generated preview images. This template is processed by eleventy. (source)
After the build step: I start a local server in the directory with the generated HTML files, open them using puppeteer and programmatically take a screenshot which is saved alongside the HTML templates. The HTML templates are then deleted.
This is integrated into the build step with a custom script that is executed after the eleventy build.
I've published the script used to take screenshots with Puppeteer as an NPM package (generate-preview-images), though it's very much still in alpha. But you can check the source code on Github to see how it works, maybe it helps with your plugin.

Xpath starting retuning None on Scrapy

I'm trying to crawl a site and to do so, I'm using Scrapy. So, when doing requests to nested pages, the procedure usually gets the the information correctly on the first trials, but, on later requests the nodes starts to return None. I'm using xpath's functionality. Below I'm pasting some lines of the parse function:
(I tried this one with the approach of explicitly comparing the class value)
title = response.xpath('//span[#class="inlineFree"]/text()').extract_first()
(With this one I used the contains function)
view = response.xpath('//span[contains(#class,"count")]/text()').extract_first()
(I've also used this one when I found more suitable)
comments = response.css('div.commentMessage > span::text').extract()
Am I doing something wrong on paths?
Is there any reason for the crawler to stop reading the nodes correctly?
Cannot say what the problem is without the log messages or the spider code but..
What happens most of the time is that websites fo not follow a strict html structure .For some properties the 'title' may be inside the span
but for the next iteration it may be
span[#class="inlineFree"]/h1/text() or or any other tag
so you should check the html for those returning None

"Two output file names resolved to the same output path" error when nesting more than one .resx file within form in .NET application

I have a Windows Forms .NET application in Visual Studio. Making a form "Localizable" adds a Form1.resx file nested below the form. I also want to add a separate .resx file for each form (Form1Resources.resx). This is used for custom form-specific resources, e.g. messages generated using the code behind.
This is set up as follows:
It would be tidier to nest the custom .resx file beneath the form (see this question for details about nest how to do this), as follows:
However, this results in the following error when I build the application:
Two output file names resolved to the same output path:
"obj\Debug\WindowsFormsApp1.Form1.resources" WindowsFormsApp1
I'm guessing that MSBuild uses some logic to find nested .resx files and generate .resources file based on its parent. Is there any way that this can be resolved?
Note that it is not possible to add custom messages to the Form1.resx file - this is for design-specific resources only and any resources that you add get overwritten when you save changes in design mode.
The error comes from the GenerateResource task because the 2 resx files (EmbeddedResource items in msbuild) passed both have the same ManifestResourceName metadata value. That values gets created by the CreateManifestResourceNames task and assumingly when it sees an EmbeddedResource which has the DependentUpon metadata set (to Form1.cs in your case) it always generates something of the form '$(RootNamespace).%(DependentUpon)': both your resx files end up with WindowsFormsApp1.Form1 as ManifestResourceName. Which could arguably be treated as the reason why having all resx files under Form1 is not tidier: it's not meant for it, requires extra fiddling, moreover it could be confusing for others since they'd typcially expect to contain the resx fils placed beneath a form to contain what it always does.
Anyway: there's at least 2 ways to work around this:
there's a Target called CreateCustomManifestResourceNames which is meant to be used for custom ManifestResourceName creation. A bit too much work for your case probably, just mentioning it for completeness
manually declare a ManifestResourceName yourself which doesn't clash with the other(s); if the metadata is already present it won't get overwritten by
Generic code sample:
<EmbeddedResource Include="Form1Resources.resx">
<DependentUpon>Form1.cs</DependentUpon>
<ManifestResourceName>$(RootNamespace).%(FileName)</ManifestResourceName>
...
</EmbeddedResource>

Meteor, coffeescript files running on every page

I am just getting started with Meteor and have encountered something that isn't necessarily an issue but something that I just don't understand. I have the following code in a file called chat.coffee...
Meteor.setInterval ( ->
console.log "Hello " + roomName
Meteor.call('keepAlive', Meteor.user(), roomName)
return
), 5000
I originally was under the impression that coffee-script files only ran on their associated html files. This doesn't seem to be the case here as this code runs on every single page regardless of the file name. Is this the intended way things are supposed to work, and if so, is there a way to enforce that only certain code runs on certain pages.
One thing to mention is that this code is running in the client side folder.
On the client side, Meteor will associate your templates with their javascript functions and helpers based upon shared template names, but that is not inherently tied to your file names.
By way of example, if you have a template named "chat" in an html file as follows:
<template name="chat"></template>
Meteor will run scripts such as Template.chat.helpers({}) or Template.chat.events({}) only in connection with the "chat" template. But that is not dependent on your file naming conventions. It could be placed in a file name chat.js for organization and convention, but could equally well reside in a file named client.js or any other arbitrarily named .js file.
Similarly, your <template name="chat"> could reside in a file named chat.html, or client.html, or an arbitrary name of your choosing.
Your setInterval function is not tied to a specific template so it will run on every page, even if it resides in a file named chat.js.
Correct.
Meteor merges all your javascript ( via coffeescript ) and all the html, which it stores in its own special way. It merges all the html in heads and body etc into a page and serves that up, and it will then render templates as you specify.
To have a more "page" oriented app you can use something like iron router.

Issue with a topjson object in a Meteor app built with coffeescript

Apologies for the lack of precision in the question, but I'm not completely sure which of possibly many things I'm doing wrong here.
I'm relatively new to Coffeescript and also geo applications in general, but here goes:
I've got a working (simple) Meteor (.7.0.1) application utilizing coffeescript in both client and server. The issue I'm having occurs when attempting to utilize TopoJSON encoded files to create a layer of US congressional districts. (the purpose of the app is to help highlight voter suppression in the US)
So, a few things: Typically in a non-Meteor app, I would just load the topoJSON file like so:
$.getJSON('./data/us-congress-113.json', function (data) {
var congress_geojson = topojson.feature(data, data.objects.districts);
congress_layer.addData(congress_geojson);
});
Now of course this won't work in Meteor because its not asynchronous.
One of the things that was recommended here on SO was to not worry about reading the file, and to instead change the json file to .js, and then set the contents (which are of course just an object) equal to a variable.
Here's what I did:
First, I changed the .json file to a .js file in the server directory, and added the "congress =" to the beginning of the file. It's a huge file so forgive me for omitting the whole object.
congress = {"type":"Topology",
"objects":
{"districts":
{"type":"GeometryCollection","geometries":[{"type":"Polygon"
Now here's where everything starts to give me issues:
In the server.coffee, I've created a variable like so to reference the congress object:
#congress_geojson = topojson.feature(congress, congress.objects.districts)
Notice how I'm putting the # symbol there? I've been told this allows a variable in Coffeescript to be globally scoped? I tried to also use a Meteor feature called "share" where I declare the variable as "share.congress_geojson". That led to the same issues which I will describe below.
Now in the client.coffee file, I'm trying to call this variable to load into a Leaflet map.
congress_layer = L.geoJson(null,
style:
color: "#DE0404"
weight: 2
opacity: 0.4
fillOpacity: 0.1
)
congress_layer.addData(#congress_geojson)
This isn't working, and specifically (despite attempts to find other ways, the errors I'm getting in the console are:
Exception from Deps afterFlush function: TypeError: Cannot read property 'features' of undefined
at o.GeoJSON.o.FeatureGroup.extend.addData (http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:39:16471)
at Object.Template.map.rendered (http://localhost:3000/client/client.coffee.js?37b1cdc5945f3407f2726a5719e1459f44d1db2d:213:18)
I have no doubt that I'm missing something stupidly obvious here. Any suggestions or tips for what I'm doing completely wrong would be appreciated. Is it a case where an object globally declared in a .js file isn't available to code in a .coffee file? Maybe I'm doing something wrong on the Meteor side?
Thanks!
Edit:
So I was able to get things working by putting the .js file containing the congress object in a root /lib folder, causing the object to load first, and then calling the congress object from the client. However, I'm still wanting to know how I could simply share this object from the server? What is the "Meteor way" here?
If you are looking for the Meteor way to order the loading of files, use the Meteor.startup function and put the initialization code there. That function is the $.ready of the Meteor world, i.e., it will execute only after all your files have been successfully loaded on the client.
So in your case:
Meter.startup ->
congress_layer.addData(#congress_geojson)