CSS missing in the eyes of Google - css

When I load the website in a browser, it shows up correctly. However, when testing it with search.google.com it shows up without style sheets (and thereby not passing the test to be suitable for mobile devices). I assume it is because of the service worker I am using. However, I don't know that the problem is with it?
Below is the full code of the service worker in place:
const
_ = {
domain: 'https://matchflix.ch/',
name: 'matchflix'
},
cachable = [_.domain, 'https://fonts.googleapis.com/', 'https://ajax.googleapis.com/'],
log = 'ServiceWorker 1.1'
;
self.addEventListener('fetch', event => {
if(event.request.method !== 'GET')
return;
if(!event.request.referrer.startsWith(_.domain))
return;
if(!cachable.some(url => event.request.url.startsWith(url)))
return;
function versionedURL(request){
switch(request.destination){
case 'image':
case 'script':
case 'style':
let
version = self.serviceWorker.scriptURL.split('?')[1]
;
return new Request(request.url + '?' + version);
default:
return request;
}
}
let
internal = event.request.url.startsWith(_.domain),
request = internal ? versionedURL(event.request) : event.request
;
event.respondWith(caches.open(_.name)
.then(cache => fetch(request)
.then(response => {
console.debug(log, 'Caching', internal, response, request);
if(internal)
cache.put(request, response.clone());
return response;
})
.catch(() => cache.match(request))
)
);
});
This is how the website looks in the eyes of Google:
What I tried so far
Commenting out the registration of the service worker, did not change anything unfortunately.
On search.google.com I saw under more information that there was an unknown error loading the script and style sheets. Unfortunately, no further information was given.

Your site is too slow. The entire page, including all assets needs to load within about 5 seconds so that Googlebot doesn't give up on rendering. I'm opening your site now and the spinner is still going after 30 seconds.

Related

MassTransit and WebApplicationFactory functional testing

I'm making use of MassTransit to receive some messages from a client's application, and redistribute the message within our environment with some routing headers added.
Whilst we are processing a high amount of messages, not all consuming applications are going to be interested in the whole set of the messages. As such the various consumers are configured with the SNS/SQS FilterPolicy attribute to ensure that only the messages we care about are consumed.
The issues I'm experiencing comes about when using the WebApplicationFactory and the IServiceCollection AddMassTransitTestHarness extension method.
The first issue might be down to my misunderstanding. As I'm using SQS/SNS specific functionality, the InMemoryTestHarness is unsuitable. I'm calling the below snippet when configuring my MassTransitTestHarness:
services.AddMassTransitTestHarness( x =>
{
RegisterConsumers( x );
x.UsingAmazonSqs( ( context, factoryConfigurator ) =>
{
factoryConfigurator.Host( new Uri( "amazonsqs://localhost:4566" ),
h =>
{
h.Config( new AmazonSimpleNotificationServiceConfig { ServiceURL = serviceUrl } );
h.Config( new AmazonSQSConfig { ServiceURL = serviceUrl } );
h.AccessKey( "test" );
h.SecretKey( "test" );
} );
RegisterReceiveEndpoints( factoryConfigurator, context );
} );
} );
protected override void RegisterConsumers( IRegistrationConfigurator configurator )
{
configurator.AddConsumer<MovementConsumer>();
}
protected override void RegisterReceiveEndpoints( IAmazonSqsBusFactoryConfigurator factoryConfigurator, IRegistrationContext context )
{
factoryConfigurator.ReceiveEndpoint( $"{ServiceConstants.ServiceName}-test-movement", endpointConfigurator =>
{
endpointConfigurator.ConfigureConsumer<MovementConsumer>( context );
endpointConfigurator.QueueSubscriptionAttributes["FilterPolicy"] = $"{{\"RoutingKey\": [\"null\"]}}";
} );
}
My first question with this approach is that is it necessary to re-register consumers? Ideally I'd like to call AddMassTransitTestHarness and just have it replace the already existing Bus with the TestHarness, but I was finding my consumers weren't being called. Having to re-register the endpoints in both the tests project and the actual project is a burden I'd like to avoid any other developers on this project having.
The second question I have is with regards to asserting against what's been published. I'm experiencing inconsistent results with the below code:
await busTestHarness.Start();
await busTestHarness.Bus.Publish( message, CancellationToken.None );
await busTestHarness.InactivityTask;
//await Task.Delay( TimeSpan.FromSeconds( 2 ) );
busTestHarness.Published.Select<T>().Any( publishedMessage => publishedMessage.Context.Headers.Any( headerValue => headerValue.Key == "RoutingKey" && (string) headerValue.Value == expectedHeader ) ).ShouldBeTrue();
Sometimes the above assertion fails. I am expecting my consumer to publish a new message with routing headers (I am not asserting against the message I publish in the test).
I've found that whilst still flakey, the 2 second delay seems to reduce the rate of failure. Is my usage of InactivityTask correct? Is there anything else I should be waiting for.
Thanks for any help, I've scoured the docs and watched the video on testing with WebApplicationFactory. I've mirrored what's done in there as best as I can. The major difference being that I am not expecting any responses from my messages.

registerFont() from node-canvas not parsing font on Firebase Cloud Functions

I am currently working on generating an image with node-canvas via Firebase Cloud Functions, then sending it as an email attachment with nodemailer.
The requirement of the image is that I need to input some string onto a template with a specific font.
So on Firebase Cloud Functions, here is what I did:
exports.test = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
functions.logger.log('tempFilePath is', tempFilePath);
bucket.file('tnr.ttf').download({destination: tempFilePath});
functions.logger.log('Font downloaded locally to', tempFilePath);
registerFont(path.resolve(tempFilePath), {family: 'tnr'});
functions.logger.log('Font registered successfully');
}
}
I have already verified repeatedly that the file 'tnr.ttf' exists on my project cloud and can successfully be loaded to that temp path.
At the registerFont function however, Firebase would always throw this error, no matter which font file I use:
Error: Could not parse font file
at registerFont (/workspace/node_modules/canvas/index.js:48:17)
Could there possibly be a problem with how Firebase handles this package or function?
You are trying to use the font before it has finished downloading. By the time you realize the problem, open up a terminal and confirm that it's actually present, the download has finished.
What you need to do is wait for either the Promise returned by download(...) to resolve or attach a callback to the download() method. Then after it's finished downloading, you can register the font.
exports.test = functions.https.onRequest((request, response) => {
cors(request, response, (corsErr) => {
if (corsErr) {
// this is rare, but still possible.
functions.logger.error('Request rejected by CORS: ', corsErr);
res.status(412).send('Rejected by CORS'); // 412 FAILED PRECONDITION
return;
}
let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
functions.logger.log('tempFilePath is ', tempFilePath);
bucket.file('tnr.ttf').download(
{destination: tempFilePath},
(err) => {
if (err) {
functions.logger.error('Failed to download font to local system: ', err);
res.status(422).send('Failed to register font'); // 422 UNPROCESSABLE ENTITY
return;
}
functions.logger.log('Font downloaded locally to ', tempFilePath);
registerFont(path.resolve(tempFilePath), {family: 'tnr'});
functions.logger.log('Font registered successfully');
res.send('Registered font successfully');
}
);
}
}
Notes:
Don't forget to properly handle errors and terminate requests properly.
The same function invocation may be invoked again, consider setting a "I already downloaded that" flag somewhere. In a "worst-case scenario", you may end up with 100s of the same font file.
Make sure to execute the registerFont method where you will be using it. You can't have separate /registerFonts and /drawWithFont endpoints, as you aren't guaranteed to be talking to the same function instance you were a moment ago.

Why is the css no longer loaded if I add a key to the url?

My app is in Koa JS.
The code below generates a website with full css (http://localhost:3000/product):
module.exports = (router, productsLoader) => {
router.get("/product", async ctx => {
const product = await productsLoader.single(ctx.params.slug)
ctx.state.model = {
title: 'Hey there,',
products: product
}
await ctx.render('product');
})
}
However if I add a key (:slug) to the url, the website can show the bare content but not any css features (http://localhost:3000/product/abc):
module.exports = (router, productsLoader) => {
router.get("/product/:slug", async ctx => {
const product = await productsLoader.single(ctx.params.slug)
if (product) {
ctx.state.model = {
title: product.name,
product: product
}
await ctx.render('product')
}
})
}
My intuition tells me it is something to do with async and await, but I couldn't find out exactly what went wrong.
edit:
In the website below, it said "So CSS doesn't get sent along with the pages in a dynamic site like this. The HTML gets sent to the client, and then the client requests the files from the server. So what I did was I added a router to the CSS in my app.js" & "But on a dynamic site, when a request is made, and a response is sent, the response is sent to the '/', and NOT to the subfolder that's on the server side (at least by default). There is no subfolder on the client's side. Responses are simply just sent to the '/' by default. So make sure that the HTML is referencing the client side's files, and not the server side's files!"
But if I have lots of css files to reference to, then that means I have to manually reference to those files again? that sounds quite counter intuitive as Koa Js is supposed to be more convenient!
https://teamtreehouse.com/community/cant-get-the-css-to-load-in-the-nodejs-server

Cypress: How to access the body of a POST-request?

Is there a way in Cypress to check the body of a POST-request?
E.g.: I have entered some data in a form, then pressed "Submit".
The form-data is send via POST-request, separated by a blank line from the header-data.
I would like to check the form-data. If all data, which I have entered, are included and if they are correct.
Is that possible with Cypress?
cy.get('#login').then(function (xhr) {
const body = xhr.requestBody;
console.log(xhr);
expect(xhr.method).to.eq('POST');
});
The xhr-object doesn't have the transferred data included.
It should be possible.
describe('Capturing data sent by the form via POST method', () => {
before(() => {
Cypress.config('baseUrl', 'https://www.reddit.com');
cy.server();
cy.route({
method: 'POST',
url: '/login'
}).as('redditLogin');
});
it('should capture the login and password', () => {
cy.visit('/login');
cy.get('#loginUsername').type('username');
cy.get('#loginPassword').type('password');
cy.get('button[type="submit"]').click();
cy.wait('#redditLogin').then(xhr => {
cy.log(xhr.responseBody);
cy.log(xhr.requestBody);
expect(xhr.method).to.eq('POST');
})
});
});
This is how you can inspect your data in Chrome Developer Tool.
You should see the same thing you've seen from Chrome Developer Tool when you run your test in Cypress.
I was Googling the same problem and somehow landed here before reaching the documentation.
Anyway, have you tried something like:
cy.wait('#login').should((xhr) => {
const body = xhr.request.body
expect(body).to.match(/email/)
})
I haven't tested it out with a multipart/form-data encoded request, but I suspect that you'll also find the request body that way.
Good luck!
It's better to use cy.intercept() in order to spy, stub and assert network requests and responses.
// assert that a request to this route
// was made with a body that included 'user'
cy.wait('#someRoute').its('request.body').should('include', 'user')
// assert that a request to this route
// received a response with HTTP status 500
cy.wait('#someRoute').its('response.statusCode').should('eq', 500)
// assert that a request to this route
// received a response body that includes 'id'
cy.wait('#someRoute').its('response.body').should('include', 'id')
Link to the docs

HTTP requests in Intel XDK

I previously built an app in the Intel XDK platform pre the Feb 23rd update and now the software has updated when i try to run the emulator it just crashes.
previously i sent a get request to a process php page for a login in the following way.
$(document).ready(function(){
$('form.login').submit(function () {
var user = $(this).find("[name='user']").val();
var pass = $(this).find("[name='pass']").val();
var sublogin = $(this).find("[name='sublogin']").val();
// ...
$.ajax({
type: "POST",
url: "http://www.domain.com/data/apps/project1/process.php",
data: {
user : user,
pass : pass,
sublogin : sublogin,
},
success: function(response){
if(response == "1")
{
$("#responsecontainer").html(response);
window.location.href = "menu.html";
}
// Login failed
else
{
$("#responsecontainer").html(response);
}
//alert(response);
}
});
this.reset();
return false;
});
});
However it seems that this is the piece of code that is causing the problems, if I remove this item of code the project no longer crashes.
When i read through the Intel XDK documents it only shows HTTP request to call XML files.
So i was hoping that somebody may know why this is causing the problem or how i might construct it so that Intel XDK doesn't crash.
There is a regression bug with regards to relative location URL referenced through emulator, a fix is being worked on. This is related to emulator only. Your app should work fine with test tab using App Preview on the device and using the build.
Till we come up with a fix for emulator crash, here is a workaround. The issue arises when you are trying to change the location of your current page with window.location.href = "menu.html"; and emulator is not able to resolve the relative path during ajax call.
Please use the following code as a workaround.
var newLocation = 'menu.html';
if ( window.tinyHippos ) {
// special case for emulator
newLocation = getWebRoot() + newLocation;
}
document.location.href=newLocation;
function getWebRoot() {
"use strict" ;
var path = window.location.href ;
path = path.substring( 0, path.lastIndexOf('/') ) ;
path += '/';
return path;
}
Swati

Resources