Skip to content
Merged

beta v2 #1801

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/selenium-ide/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "selenium-ide",
"version": "4.0.1-beta.1",
"version": "4.0.1-beta.2",
"private": false,
"description": "Selenium IDE electron app",
"author": "Todd <tarsitodd@gmail.com>",
Expand Down Expand Up @@ -112,16 +112,16 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@fontsource/roboto": "^5.0.8",
"@mui/icons-material": "^5.15.0",
"@mui/material": "^5.15.0",
"@mui/icons-material": "^5.15.13",
"@mui/material": "^5.15.13",
"@seleniumhq/code-export-csharp-nunit": "^4.0.1",
"@seleniumhq/code-export-csharp-xunit": "^4.0.1",
"@seleniumhq/code-export-java-junit": "^4.0.1",
"@seleniumhq/code-export-javascript-mocha": "^4.0.1",
"@seleniumhq/code-export-python-pytest": "^4.0.1",
"@seleniumhq/code-export-ruby-rspec": "^4.0.1",
"@seleniumhq/get-driver": "^4.0.1",
"@seleniumhq/side-api": "^4.0.1",
"@seleniumhq/side-api": "^4.0.2",
"@seleniumhq/side-commons": "^4.0.1",
"@seleniumhq/side-model": "^4.0.1",
"@seleniumhq/side-runtime": "^4.0.1",
Expand Down
23 changes: 16 additions & 7 deletions packages/selenium-ide/scripts/ide-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,28 @@ async function main() {
} catch (e) {}
}
await driver.switchTo().window(handles[0])

const projectTab = await driver.wait(
webdriver.until.elementLocated(webdriver.By.id('tab-2')),
5000
)
await projectTab.click()

const url = await driver.wait(
webdriver.until.elementLocated(webdriver.By.css('[data-url]')),
webdriver.until.elementLocated(webdriver.By.id('project-url')),
5000
)
await url.click()
while ((await url.getAttribute('value')) !== '') {
await url.sendKeys(webdriver.Key.BACK_SPACE)
}
const host = 'http://localhost:8080'
for (const index in host) {
await url.sendKeys(host[index])
await driver.sleep(10)
}
await url.sendKeys('http://localhost:8080')

const testTab = await driver.wait(
webdriver.until.elementLocated(webdriver.By.id('tab-0')),
5000
)
await testTab.click()

const record = await driver.wait(
webdriver.until.elementLocated(webdriver.By.css('[data-record]')),
1000
Expand Down
16 changes: 8 additions & 8 deletions packages/selenium-ide/src/browser/components/AppBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import MenuIcon from '@mui/icons-material/Menu'
import MenuOpenIcon from '@mui/icons-material/MenuOpen'
import React from 'react'
import TabPanel from '../Tab/Panel'
import React, { useContext } from 'react'
import SuiteControls from 'browser/windows/ProjectEditor/tabs/Suites/Controls'
import TestControls from 'browser/windows/ProjectEditor/tabs/Tests/Controls'
import { SUITES_TAB, TESTS_TAB } from 'browser/enums/tab'
import { SIDEMainProps } from '../types'
import AppBarTabs from './AppBarTabs'
import IconButton from '@mui/material/IconButton'
import Paper from '@mui/material/Paper'
import { getActiveTest } from '@seleniumhq/side-api'
import { context } from 'browser/contexts/show-drawer'
import baseControlProps from '../Controls/BaseProps'
import TabPanel from '../Tab/Panel'

type SIDEAppBarProps = Pick<SIDEMainProps, 'session' | 'setTab' | 'tab'>
type SIDEAppBarProps = Pick<SIDEMainProps, 'setTab' | 'tab'>

const SIDEAppBar: React.FC<SIDEAppBarProps> = ({ session, setTab, tab }) => {
const showDrawer = session.state.editor.showDrawer
const SIDEAppBar: React.FC<SIDEAppBarProps> = ({ setTab, tab }) => {
const showDrawer = useContext(context)
return (
<Paper className="flex flex-row width-100 z-3" elevation={1} square>
<IconButton
Expand All @@ -30,10 +30,10 @@ const SIDEAppBar: React.FC<SIDEAppBarProps> = ({ session, setTab, tab }) => {
<AppBarTabs setTab={setTab} tab={tab} />
<div className="flex flex-1" />
<TabPanel index={TESTS_TAB} value={tab}>
<TestControls state={session.state} test={getActiveTest(session)} />
<TestControls />
</TabPanel>
<TabPanel index={SUITES_TAB} value={tab}>
<SuiteControls state={session.state} />
<SuiteControls />
</TabPanel>
</Paper>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import PlayArrowIcon from '@mui/icons-material/PlayArrow'
import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip'
import { StateShape } from '@seleniumhq/side-api'
import React, { FC } from 'react'
import React, { FC, useContext } from 'react'
import { badIndex } from '@seleniumhq/side-api/dist/constants/badIndex'
import baseControlProps from './BaseProps'
import { context as playbackCurrentIndexContext } from 'browser/contexts/playback-current-index'
import { context as activeTestContext } from 'browser/contexts/active-test'

export interface PlayButtonProps {
state: StateShape
const PlayButton: FC = () => {
const { activeTestID } = useContext(activeTestContext)
const currentIndex = useContext(playbackCurrentIndexContext)
return (
<Tooltip title="Play" aria-label="play">
<IconButton
{...baseControlProps}
data-play
onClick={() => {
currentIndex === badIndex
? window.sideAPI.playback.play(activeTestID)
: window.sideAPI.playback.resume()
}}
>
<PlayArrowIcon />
</IconButton>
</Tooltip>
)
}

const PlayButton: FC<PlayButtonProps> = ({ state }) => (
<Tooltip title="Play" aria-label="play">
<IconButton
{...baseControlProps}
data-play
onClick={() => {
state.playback.currentIndex === badIndex
? window.sideAPI.playback.play(state.activeTestID)
: window.sideAPI.playback.resume()
}}
>
<PlayArrowIcon />
</IconButton>
</Tooltip>
)

export default PlayButton
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import PlaylistPlayIcon from '@mui/icons-material/PlaylistPlay'
import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip'
import { StateShape } from '@seleniumhq/side-api'
import React, { FC } from 'react'
import baseControlProps from './BaseProps'

export interface PlayListButtonProps {
state: StateShape
}

const PlayListButton: FC<PlayListButtonProps> = () => (
const PlayListButton: FC = () => (
<Tooltip title="Play Suite" aria-label="play-suite">
<IconButton
{...baseControlProps}
Expand Down
15 changes: 4 additions & 11 deletions packages/selenium-ide/src/browser/components/Drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,18 @@ import TestsDrawer from 'browser/windows/ProjectEditor/tabs/Tests/TestsDrawer'
import SuitesDrawer from 'browser/windows/ProjectEditor/tabs/Suites/SuitesDrawer'
import ProjectDrawer from 'browser/windows/ProjectEditor/tabs/Project/ProjectDrawer'

const SIDEDrawer: React.FC<Pick<SIDEMainProps, 'session' | 'tab'>> = ({
session,
const SIDEDrawer: React.FC<Pick<SIDEMainProps, 'tab'>> = ({
tab,
}) => (
<>
<TabPanel index={TESTS_TAB} value={tab}>
<TestsDrawer
session={session}
/>
<TestsDrawer />
</TabPanel>
<TabPanel index={SUITES_TAB} value={tab}>
<SuitesDrawer
session={session}
/>
<SuitesDrawer />
</TabPanel>
<TabPanel index={PROJECT_TAB} value={tab}>
<ProjectDrawer
session={session}
/>
<ProjectDrawer />
</TabPanel>
</>
)
Expand Down
67 changes: 67 additions & 0 deletions packages/selenium-ide/src/browser/components/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { ChangeEvent, FocusEvent } from 'react';

type Props = React.HTMLAttributes<HTMLInputElement> & {
value: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
onFocus: (e: FocusEvent<HTMLInputElement>) => void;
onBlur: (e: FocusEvent<HTMLInputElement>) => void;
}

type State = {
isFocused: boolean;
currentValue: string;
}

class Input extends React.Component<Props, State> {
static defaultProps: Partial<Props> = {
onChange: () => {},
onFocus: () => {},
onBlur: () => {}
};

state: State = {
isFocused: false,
currentValue: this.props.value
};

static getDerivedStateFromProps(nextProps: Props, prevState: State) {
// This lifecycle method does not have access to 'this',
// so you cannot directly compare with 'this.state'.
// Instead, it receives the next props and previous state:
if (!prevState.isFocused) {
return { currentValue: nextProps.value };
}
return null; // Return null to indicate no change to state.
}

handleChange = (e: ChangeEvent<HTMLInputElement>) => {
this.setState({ currentValue: e.target.value });
this.props.onChange(e);
};

handleFocus = (e: FocusEvent<HTMLInputElement>) => {
this.setState({ isFocused: true });
this.props.onFocus(e);
};

handleBlur = (e: FocusEvent<HTMLInputElement>) => {
this.setState({ isFocused: false });
this.props.onBlur(e);
};

render() {
// Destructuring to avoid passing internal methods or state as props to the input element
const { value, onChange, onFocus, onBlur, ...rest } = this.props;
return (
<input
{...rest}
onChange={this.handleChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
value={this.state.currentValue}
/>
);
}
}

export default Input;
51 changes: 27 additions & 24 deletions packages/selenium-ide/src/browser/components/Logger/index.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
import Delete from '@mui/icons-material/Delete'
import { Paper } from '@mui/material'
import IconButton from '@mui/material/IconButton'
import { LogLevel } from 'electron-log'
import React from 'react'
import Delete from '@mui/icons-material/Delete';
import { Paper, IconButton } from '@mui/material';
import React from 'react';

const consoleStyle = {
fontSize: '0.75rem',
lineHeight: '1.2',
}
};

const SIDELogger: React.FC = () => {
const logContainer = React.useRef<HTMLPreElement>(null)
const logContainer = React.useRef<HTMLPreElement>(null);

const handleLog = React.useCallback((level: string, log: string) => {
const el = logContainer.current;
if (!el) return;
const newLogEntry = document.createTextNode(
`${new Date().toLocaleTimeString()} [${level}] ${log}\n`
);
el.appendChild(newLogEntry);
el.scrollTo(0, el.scrollHeight);
}, []); // useCallback ensures this function is memoized and not recreated on each render.

React.useEffect(() => {
const handleLog = (level: LogLevel, log: string) => {
const el = logContainer.current
if (!el) return;
el.append(
`${new Date().toLocaleTimeString()} [${level}] ${log}\n`
)
el.scrollTo(0, el.scrollHeight)
}
window.sideAPI.system.onLog.addListener(handleLog)
window.sideAPI.system.onLog.addListener(handleLog);
return () => {
window.sideAPI.system.onLog.removeListener(handleLog)
}
}, [logContainer])
window.sideAPI.system.onLog.removeListener(handleLog);
};
}, [handleLog]); // Depend on handleLog which is now memoized.

return (
<>
<div className="p-1 pos-abs" style={{ top: 0, right: 0 }}>
<Paper className="p-1" elevation={3} square>
<IconButton
onClick={() => {
if (logContainer.current) {
logContainer.current.innerHTML = ''
const el = logContainer.current;
if (el) {
el.textContent = ''; // Safer and potentially faster than innerHTML
}
}}
>
Expand All @@ -46,7 +49,7 @@ const SIDELogger: React.FC = () => {
style={consoleStyle}
/>
</>
)
}
);
};

export default SIDELogger
export default SIDELogger;
21 changes: 4 additions & 17 deletions packages/selenium-ide/src/browser/components/Main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,19 @@ import SuitesTab from '../../windows/ProjectEditor/tabs/Suites/SuitesTab'
import TestsTab from '../../windows/ProjectEditor/tabs/Tests/TestsTab'
import { SIDEMainProps } from '../types'

const SIDEMain: React.FC<Pick<SIDEMainProps, 'session' | 'setTab' | 'tab'>> = ({
session,
const SIDEMain: React.FC<Pick<SIDEMainProps, 'setTab' | 'tab'>> = ({
setTab,
tab,
}) => (
<>
<TabPanel index={TESTS_TAB} value={tab}>
<TestsTab
session={session}
setTab={setTab}
tab={tab}
/>
<TestsTab />
</TabPanel>
<TabPanel index={SUITES_TAB} value={tab}>
<SuitesTab
session={session}
setTab={setTab}
tab={tab}
/>
<SuitesTab />
</TabPanel>
<TabPanel index={PROJECT_TAB} value={tab}>
<ProjectTab
session={session}
setTab={setTab}
tab={tab}
/>
<ProjectTab setTab={setTab} tab={tab} />
</TabPanel>
</>
)
Expand Down
Loading