cómo corregir las advertencias 404 para imágenes durante la prueba de la unidad de karma

84

Estoy probando unitariamente una de mis directivas (angularjs) usando grunt / karma / phantomjs / jasmine. Mis pruebas funcionan bien

describe('bar foo', function () {
    beforeEach(inject(function ($rootScope, $compile) {
        elm = angular.element('<img bar-foo src="img1.png"/>');
        scope = $rootScope.$new();
        $compile(elm)();
        scope.$digest();
    }));
    ....
});

pero consigo estos 404

WARN [web-server]: 404: /img1.png
WARN [web-server]: 404: /img2.png
...

Aunque no hacen nada, agregan ruido a la salida del registro. ¿Hay alguna forma de solucionar este problema? (sin cambiar el nivel de registro de karma, por supuesto, porque quiero verlos)

Jeanluca Scaljeri
fuente
¿Persiste en un navegador diferente? Sé que hay algunos problemas conocidos con errores 404 para este tipo de llamadas en FF.
Nicholas Hazel
tiene que ser phantomjs. Revisé Chrome, que también muestra el 404. Tenga en cuenta que son advertencias, no errores.
Jeanluca Scaljeri
¿El uso de ng-src ayuda?
Eitan Peer
Buen

Respuestas:

109

Eso se debe a que necesita configurar karma para cargar y luego servirlos cuando se le solicite;)

En su archivo karma.conf.js ya debería tener archivos y / o patrones definidos como:

// list of files / patterns to load in the browser
files : [
  {pattern: 'app/lib/angular.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/angular-*.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'app/js/**/*.js', watched: true, included: true, served: true},
  // add the line below with the correct path pattern for your case
  {pattern: 'path/to/**/*.png', watched: false, included: false, served: true},
  // important: notice that "included" must be false to avoid errors
  // otherwise Karma will include them as scripts
  {pattern: 'test/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'test/unit/**/*.js', watched: true, included: true, served: true},
],

// list of files to exclude
exclude: [

],

// ...

Puedes echar un vistazo aquí para más información :)

EDITAR: Si usa un servidor web nodejs para ejecutar su aplicación, puede agregar esto a karma.conf.js:

proxies: {
  '/path/to/img/': 'http://localhost:8000/path/to/img/'
},

EDIT2: Si no usa o no desea usar otro servidor, puede definir un proxy local, pero como Karma no proporciona acceso al puerto en uso, dinámicamente, si karma comienza en otro puerto que no sea 9876 (predeterminado), aún lo hará conseguir esos molestos 404 ...

proxies =  {
  '/images/': '/base/images/'
};

Problema relacionado: https://github.com/karma-runner/karma/issues/872

glepretre
fuente
4
En mi caso estas imágenes no existen. La solución que proporciona asume que los archivos existen, ¿verdad?
Jeanluca Scaljeri
¡Sí, por supuesto! Creo que lo entendí mal, tiene sentido tener errores 404 para archivos que no existen, ¿verdad? ¿Le gustaría ocultar las advertencias relacionadas con las imágenes? Sin cambiar el nivel de registro, no veo ninguna solución, además, que esconda otras advertencias, lo que sería riesgoso. ¿Por qué no crear archivos .png vacíos en la carpeta "test / img", por ejemplo? :)
glepretre
Por alguna razón, no puedo hacer que funcione. ¿Cuál es exactamente la relación entre la URL utilizada en el HTML y el patrón en karma.conf.js? Por ejemplo, si tengo una imagen en test / assets / img.png , ¿cuál debería ser la URL?
Jeanluca Scaljeri
1
Mis disculpas, esta solución debería funcionar, pero también seguí recibiendo errores 404. Creo que esto está relacionado con la falta de implementación en Karma y me sorprende que seamos los únicos en conseguirlo. Encontré una forma (un poco hacky) de hacer que esto funcione, pero necesitarás ejecutar otro servidor (web) en paralelo a Karma. Editaré mi respuesta. ;)
glepretre
3
En respuesta a EDIT2, si ejecuta karma en un puerto personalizado, puede evitar los 404 vinculando al URI completo del servidor de karma: (asumiendo port: 9999)proxies = { '/images/': 'http://localhost:9999/base/images/' };
Josh
18

La pieza confusa del rompecabezas para mí fue la carpeta virtual "base". Si no sabe que debe incluirse en las rutas de activos de sus dispositivos, le resultará difícil depurarlo.

Según la documentación de configuración

De forma predeterminada, todos los activos se sirven en http: // localhost: [PORT] / base /

Nota: esto puede no ser cierto para otras versiones: estoy en 0.12.14 y funcionó para mí, pero los documentos 0.10 no lo mencionan.

Después de especificar el patrón de archivos:

{ pattern: 'Test/images/*.gif', watched: false, included: false, served: true, nocache: false },

Podría usar esto en mi accesorio:

<img src="base/Test/images/myimage.gif" />

Y no necesitaba el proxy en ese momento.

Tom Elmore
fuente
Este es el factor decisivo. La respuesta principal explica esto, pero muy brevemente: gracias por expandir.
jlb
10

Puede crear middleware genérico dentro de su karma.conf.js, un poco exagerado, pero hizo el trabajo por mí

Primero defina imágenes ficticias de 1px (he usado base64):

const DUMMIES = {
  png: {
    base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
    type: 'image/png'
  },
  jpg: {
    base64: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigD//2Q==',
    type: 'image/jpeg'
  },
  gif: {
    base64: 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=',
    type: 'image/gif'
  }
};

Luego defina la función de middleware:

function surpassImage404sMiddleware(req, res, next) {
  const imageExt = req.url.split('.').pop();
  const dummy = DUMMIES[imageExt];

  if (dummy) {
    // Table of files to ignore
    const imgPaths = ['/another-cat-image.png'];
    const isFakeImage = imgPaths.indexOf(req.url) !== -1;

    // URL to ignore
    const isCMSImage = req.url.indexOf('/cms/images/') !== -1;

    if (isFakeImage || isCMSImage) {
      const img = Buffer.from(dummy.base64, 'base64');
      res.writeHead(200, {
        'Content-Type': dummy.type,
        'Content-Length': img.length
      });
      return res.end(img);
    }
  }
  next();
}

Aplicar middleware en su configuración de karma

{
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    middleware: ['surpassImage404sMiddleware'],
    plugins: [
      ...
      {'middleware:surpassImage404sMiddleware': ['value', surpassImage404sMiddleware]}
    ],
    ...
}
Jakub Żwirko
fuente
¿Alguna vez lo convirtió en un paquete real? Me encantaría instalar esto
npm
Si desea suprimir todas las solicitudes de imágenes, solo verifique req.headers.acceptsi contiene imagey devuelva 204 si lo hace.
Cleong
9

Según la respuesta de @ glepretre, creé un archivo .png vacío y lo agregué a la configuración para ocultar las advertencias 404:

proxies: {
  '/img/generic.png': 'test/assets/img/generic.png'
}
the_karel
fuente
3

Para solucionarlo, karma.conf.jsasegúrese de señalar el archivo servido con sus proxies:

files: [
  { pattern: './src/img/fake.jpg', watched: false, included: false, served: true },
],
proxies: {
  '/image.jpg': '/base/src/img/fake.jpg',
  '/fake-avatar': '/base/src/img/fake.jpg',
  '/folder/0x500.jpg': '/base/src/img/fake.jpg',
  '/undefined': '/base/src/img/fake.jpg'
}
Boris Yakubchik
fuente
3

A pesar de que es un hilo antiguo, me tomó un par de horas lograr que mi imagen fuera realmente servida por el karma para eliminar el 404. Los comentarios no fueron lo suficientemente completos. Creo que puedo aclarar la solución con esta captura de pantalla. Básicamente, lo único que faltaba en muchos comentarios es el hecho de que el valor del proxy debe comenzar con "/ base" , aunque la base no está en ninguna de las rutas de mi carpeta, ni en mis solicitudes.

("base" sin la barra inclinada hacia adelante resultó en que el karma devolviera un 400 MALA PETICIÓN)

Ahora, después de ejecutar la prueba ng , puedo servir correctamente "./src/assets/favicon.png" desde la URL: http: // localhost: 9876 / test / dummy.png

En mi proyecto, estoy usando las siguientes versiones del paquete npm:

  • karma v4.3.0
  • jazmín-core v3.2.1
  • karma-jazmín v1.1.2
  • @ angular / cli v8.3.5
  • angular v8.2.7

Estructura del proyecto VSCode con ubicaciones de activos karma.conf.js

Jeff
fuente
Esta información fue particularmente útil para mí para comprender que hay una diferencia (desde la perspectiva de Karma) para entregar archivos dentro del área de la base y desde fuera del área de la base (que en última instancia fue mi problema), lo que luego me llevó a github.com/karma -runner / karma / issues / 2703 . Entonces, gracias por esta aclaración.
dpmott
2

Si tiene una ruta raíz en algún lugar de su archivo de configuración, también puede usar algo como esto:

proxies: {
  '/bower_components/': config.root + '/client/bower_components/'
}
Gucu112
fuente