Skip to content

Commit

Permalink
chore: correctly resolve url sass bundle in Angular CT (#25191)
Browse files Browse the repository at this point in the history
Co-authored-by: Zachary Williams <zachjw34@gmail.com>
  • Loading branch information
lmiller1990 and ZachJW34 committed Dec 16, 2022
1 parent cd4bc74 commit 331c1dc
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 17 deletions.
33 changes: 31 additions & 2 deletions npm/webpack-dev-server/src/helpers/angularHandler.ts
@@ -1,10 +1,13 @@
import * as fs from 'fs-extra'
import { tmpdir } from 'os'
import * as path from 'path'
import type { Configuration } from 'webpack'
import type { Configuration, RuleSetRule } from 'webpack'
import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer'
import { dynamicAbsoluteImport, dynamicImport } from '../dynamic-import'
import { sourceDefaultWebpackDependencies } from './sourceRelativeWebpackModules'
import debugLib from 'debug'

const debug = debugLib('cypress:webpack-dev-server:angularHandler')

export type BuildOptions = Record<string, any>

Expand Down Expand Up @@ -250,7 +253,33 @@ async function getAngularCliWebpackConfig (devServerConfig: AngularWebpackDevSer
const { config } = await generateBrowserWebpackConfigFromContext(
buildOptions,
context,
(wco: any) => [getCommonConfig(wco), getStylesConfig(wco)],
(wco: any) => {
const stylesConfig = getStylesConfig(wco)

// We modify resolve-url-loader and set `root` to be `projectRoot` + `sourceRoot` to ensure
// imports in scss, sass, etc are correctly resolved.
// https://github.com/cypress-io/cypress/issues/24272
stylesConfig.module.rules.forEach((rule: RuleSetRule) => {
rule.rules?.forEach((ruleSet) => {
if (!Array.isArray(ruleSet.use)) {
return
}

ruleSet.use.map((loader) => {
if (typeof loader !== 'object' || typeof loader.options !== 'object' || !loader.loader?.includes('resolve-url-loader')) {
return
}

const root = path.join(devServerConfig.cypressConfig.projectRoot, projectConfig.sourceRoot)

debug('Adding root %s to resolve-url-loader options', root)
loader.options.root = path.join(devServerConfig.cypressConfig.projectRoot, projectConfig.sourceRoot)
})
})
})

return [getCommonConfig(wco), stylesConfig]
},
)

delete config.entry.main
Expand Down
@@ -1,3 +1,4 @@
// Keep this test very simple as "@cypress/schematic" relies on it to run smoke tests
import { AppComponent } from './app.component'

it('should', () => {
Expand Down
@@ -1 +1 @@
<h1>Hello World your app is running!</h1>
<h1>Hello World your app is running!</h1>
@@ -1,3 +1,3 @@
h1 {
color: red
}
}
@@ -0,0 +1,6 @@
.test-img {
background-image: url("/assets/test.png");
background-size: contain;
height: 100px;
width: 100px;
}
@@ -0,0 +1,8 @@
import { Component } from '@angular/core'

@Component({
selector: 'app-url-image',
template: `<div class="test-img"></div>`,
styleUrls: ['./url-image.component.scss'],
})
export class UrlImageComponent {}
38 changes: 25 additions & 13 deletions system-tests/project-fixtures/angular/src/app/mount.cy.ts
Expand Up @@ -20,6 +20,7 @@ import { LogoComponent } from './components/logo.component'
import { TransientService, TransientServicesComponent } from './components/transient-services.component'
import { ComponentProviderComponent, MessageService } from './components/component-provider.component'
import { Cart, ProductComponent } from './components/cart.component'
import { UrlImageComponent } from './components/url-image.component'

@Component({
template: `<app-projection>Hello World</app-projection>`,
Expand Down Expand Up @@ -360,9 +361,20 @@ describe('angular mount', () => {
cy.get('p').should('have.text', 'Hi . ngOnInit fired: true and ngOnChanges fired: false and conditionalName: false')
})

it('can load static assets', () => {
cy.mount(LogoComponent)
cy.get('img').should('be.visible').and('have.prop', 'naturalWidth').should('be.greaterThan', 0)
context('assets', () => {
it('can load static assets from <img src="..." />', () => {
cy.mount(LogoComponent)
cy.get('img').should('be.visible').and('have.prop', 'naturalWidth').should('be.greaterThan', 0)
})

it('can load root relative scss "url()" assets', () => {
cy.mount(UrlImageComponent)
cy.get('.test-img')
.invoke('css', 'background-image')
.then((img) => {
expect(img).to.contain('__cypress/src/test.png')
})
})
})

context('dependency injection', () => {
Expand Down Expand Up @@ -430,27 +442,27 @@ describe('angular mount', () => {

describe('teardown', () => {
beforeEach(() => {
cy.get("[id^=root]").should("not.exist");
});
cy.get('[id^=root]').should('not.exist')
})

it("should mount", () => {
cy.mount(ButtonOutputComponent);
});
it('should mount', () => {
cy.mount(ButtonOutputComponent)
})

it('should remove previous mounted component', () => {
cy.mount(ChildComponent, {componentProperties: { msg: 'Render 1' }})
cy.mount(ChildComponent, { componentProperties: { msg: 'Render 1' } })
cy.contains('Render 1')
cy.mount(ChildComponent, {componentProperties: { msg: 'Render 2' }})
cy.mount(ChildComponent, { componentProperties: { msg: 'Render 2' } })
cy.contains('Render 2')

cy.contains('Render 1').should('not.exist')
cy.get('[id^=root]').children().should('have.length', 1)
})
});
})

it('should error when passing in undecorated component', () => {
Cypress.on('fail', (err) => {
expect(err.message).contain("Please add a @Pipe/@Directive/@Component");
expect(err.message).contain('Please add a @Pipe/@Directive/@Component')

return false
})
Expand All @@ -459,4 +471,4 @@ describe('angular mount', () => {

cy.mount(MyClass)
})
});
})
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

4 comments on commit 331c1dc

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 331c1dc Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.2.0/linux-arm64/develop-331c1dcc9c3f4d4212e27290d705ed94ba58c3d0/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 331c1dc Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.2.0/linux-x64/develop-331c1dcc9c3f4d4212e27290d705ed94ba58c3d0/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 331c1dc Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.2.0/darwin-x64/develop-331c1dcc9c3f4d4212e27290d705ed94ba58c3d0/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 331c1dc Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/12.2.0/win32-x64/develop-331c1dcc9c3f4d4212e27290d705ed94ba58c3d0/cypress.tgz

Please sign in to comment.